Skip to content

Tag-icone-mini.png Desenvolvimento

Guia de programação
Padrões Delphi
Filosofias
Interface Commerce
Uso de componentes
Mais sobre Interface
Documentação em Fontes
Estrutura de Pastas

Padrão De Programação Em Delphi ​

Os seguintes itens são visados com a implantação deste padrão:

  • Aumentar a velocidade de programação;
  • Facilitar a manutenção do sistema;
  • Reduzir erros de programação;
  • Identificar e localizar mais rapidamente os erros de execução e programação;
  • Facilitar o desenvolvimento em conjunto;
  • Melhorar a qualidade dos sistemas.

Nomenclaturas ​

Para evitar conflitos de configurações, as nomenclaturas não devem conter caracteres especiais e acentos. Um caracter especial em um computador configurado para a língua portuguesa pode se comportar estranhamente em um computador configurado para a língua estrangeira. Existem também alguns softwares que não aceitam certos tipos de caracteres especiais ou o usam para o seu próprio controle.

Uma abreviação usada em um sistema deve permanecer a mesma em outro sistema. Para que isso acontece, o programador deverá criar uma lista contendo as abreviações já usadas.

Arquivos ​

A nomenclatura de um arquivo precisa facilitar ao máximo sua identificação e seleção. Para isso, o nome de um arquivo deve conter as seguintes informações: nome ou tipo de sistema; tipo de arquivo; finalidade do arquivo. Estas três informações servem para facilitar a identificação. E devem estar dispostos em ordem e ocupar uma quantidade pré-deteminada de caracteres. Este requisito facilita a seleção. Exemplo, conforme o padrão de nome de arquivos mostrado mais adiante: para localizar todos os datamodules do Totali Commerce e copiar para uma unidade qualquer, podemos usar a seguinte máscara de busca TTD?????.*.

TTFCDPAR.png

Quantidade de letrasDescrição
2 letrasTT para indicar que é arquivo da Totali
1 letraIndicar o tipo do Arquivo:
  F - Formulário
  D - DataModule
  R - Relatório
  U - Funções ou Classes
  C - Componente
  E - Frames
  W - WebModules
livreIdentificação do arquivo

Exemplos de nomes possíveis para alguns arquivos:

Tipo de arquivoDescriçãoNomenclatura
Unidade FormulárioParceiroTTFCDPAR
Unidade FormulárioProdutoTTFCDPRO
Unidade FormulárioPedidoTTFCDPED
Unidade FormulárioBusca de ParceiroTTFLCPAR
Unidade DataModuleDataModule para PedidoTTDCDPED
Unidade FunçõesContém as funções generalizadasTTUFNGER

Identificação do Projeto ​

Para a definição do nome do projeto também deverão ser usadas apenas 8 letras.

Variáveis, constantes, componentes, identificadores e procedimentos

Nome de variáveis, de constantes, e de componentes, devem seguir um padrão que facilite sua identificação e localização. Exemplo, conforme padrão que será mostrado mais adiante: quando quisermos alterar cliente por fornecedor basta substituirmos "Cliente" por "Fornecedor" e "Cli" por "For". Primeiro porque o padrão estipula que as nomenclaturas devem estar no singular, e segundo, porque as abreviaturas só podem ocupar 3 casas, nem mais, nem menos; outro exemplo: através do nome ed_NomCli podemos concluir que se trata de um componente de edição contendo o nome do cliente; enquanto que cCliente podemos concluir que se trata de uma variável alfanumérica contendo a descrição do cliente.

Quando houver dualidade de nomes, deve-se acrescentar no final dos nomes uma características que os diferencie. Exemplo: Se em um mesmo formulários forem usados dois componentes DBLoockupComboBox, um para representar a cidade atual e outro para a cidade de nascença. Ambos os componentes iniciariam o nome em cb_Endereco, sendo que o primeiro se chamaria cb_EnderecoAtual e o outro cb_EnderecoNas. Usar nome de variáveis que expressem, com clareza, o seu significado.

Nome de variáveis e constantes ​

Variáveis são todas as declarações feitas no identificador VAR. Os nomes das variáveis são identificados pelas letras iniciais conforme seu tipo e sub-tipo, as demais variam entre maiúsculo e minúsculo sendo que a letra maiúscula indica o início de uma nova sentença, que pode ser uma palavra inteira ou uma palavra abreviada, se for abreviada deve conter sempre 3 caracteres, caso não seja possível, não se abrevia.

Quadro de tipos para as variáveis:

Tipo de VariávelSímbolo
Caracteresc
Números Reaisn
Números Inteirosi
Vetora
Data e/ou Horad
Registror
Objetoo
Lógicob
Textot
TipoT
Procedimentalx
Parâmetrop
Variantv
Variável públicapu
Constantes públicasdf
Constantes privadasMaiúsculo s/ iniciais
Atributos privadosF

Variáveis tipo "o" - Objetos criados em tempo de execução devem identificar também um subtipo que pode ser uma descrição no singular da característica do objeto ou o próprio nome da classe do objeto.

Exemplos: cCodUsu representa o código do funcionário, cDescricao representa uma descrição, pNomUsuario nome do usuário passado como parâmetro, oListBoxUsuario ou oListaUsuario ou oListaUsu variável objeto contendo um componente tipo lista.

Contadores de loops não precisam obedecer a uma convenção de nomes.

Componentes ​

As duas letras iniciais em minúsculo, seguidas de um sublinhado, definem o tipo de componente, as demais variam entre maiúsculo e minúsculo sendo que a letra maiúscula indica o início de uma nova sentença, que pode ser uma palavra inteira ou uma palavra abreviada, se for abreviada deve conter sempre 3 caracteres, nem mais, nem menos. Exemplos: Um componente DBEdit relacionado ao nome do cliente se chamaria ed_NomeCliente ou ed_NomCliente ou ed_NomCli ou mesmo ed_NomeCli.

Os componentes que são apenas incluídos em um formulário mas não possuem eventos nem são referenciados na implementação, não precisam ser nomeados.

Lista com as iniciais de algumas componentes pela característica:

CaracterísticaAbrev.
Caracteresc
Listaslt_
Editsed_
Memosme_
Botõesbt_
Combocb_
Checkck_
DataSetsqr_
DataSourceds_
Gridsgd_
Imagensim_
Navegadoresnv_
Labelslb_
Paginadoresnb_
Páginaspg_
Formfrm
Datamodulesdm
Gaugesga_
Desenhos ou interfacesde_
Containerspn_
Menumn_
Item de Menumi_
Dialogdg_
Reportsrp_
Data e/ou Horadt_

Demais componentes usar o tipo como abreviação.

O DataSource deve ter o mesmo nome do DataSet, apenas mudando o prefixo.

Procedimentos e Funções ​

Variam entre maiúsculo e minúsculo sendo que a letra maiúscula indica o início de uma nova sentença, devendo sempre iniciar com verbos na voz ativa (Calcule, Execute, Mostre...). Funções criadas com o objetivo de fazer verificações devem iniciar com "Check" ou "Is". Exemplo: CheckLimiteCredito, IsVendaConsumidor. Métodos para obter um determinado valor deve iniciar com "Get", para atualizar um determinado valor deve iniciar com "Set". Quando um método se comportar como um evento ele deve ser iniciado por "Do".

Exemplo:

Vamos imaginar um programa simples para gerar orçamento, onde o usuário possa escolher um cliente e o sistema automaticamente salve as informações do cliente (Nome, SobreNome, CGC, Telefone em "variáveis") e mostre na tela os endereços do cliente, desabilitando alguns componentes conforme o tipo (Físico ou Jurídico).

Em um primeiro passo podemos criar uma função chamada AtualizeCliente que faça a mudança de cliente. Ou seja, altera o código do cliente na tabela principal.

Até aqui tudo bem, Agora precisamos atualizar as informações do cliente em "variáveis", mostrar os endereços e desabilitar os componentes conforme o tipo de cliente.

Não podemos colocar isso dentro da função AtualizeCliente por uma razão bem simples. Por exemplo: ao abrirmos um outro orçamento automaticamente termos que atualizar os endereços e as informações dos clientes.

Obviamente precisaremos criar uma função específica para este tratamento. Uma função que será chamada sempre que for mudado o cliente.

Essa função será precedida das iniciais Do. Neste caso: DoMudouCliente. Que podemos entender da seguinte forma DispareClienteMudou.

AtualizeCliente é uma função e DoMudouCliente é um "evento" disparado por AtualizaCliente e por AbraOrçamento.

Desta forma sempre que alguém precise fazer qualquer alteração no fonte que dependa de uma informação do cliente, ou simplesmente incluir uma nova informação. Saberá exatamente onde procurar.

Identificadores ​

Identificadores devem estar sempre com letras minúsculas.

Ex.:

  • begin;
  • end;
  • while;
  • if.

Regras ​

Eliminar dualidades ​

Para os comandos, identificadores, propriedades e eventos diferentes, mas com as mesmas finalidades, devemos definir qual deve ser o usado no intuito de tornar o programa fonte mais claro:

Usar FieldByName ao invés do objeto de campo gerado no Fields Editor; Não usar mais a função StrTran, usar StringReplace; Não usar mais a função Alinhamento usar LPad; Abort deve ser usado somente quando desejar limpar a pilha de processos; Exit deve ser usado somente para abortar um procedimento; Break para abortar loops; Para abrir tabela usar open, evitar usar active = true. Usar propriedade AsString ao invés de AsText na função FieldByName; Usar função Mensagem ao invés de ShowMessage ou MesageDlg

Alinhamento ​

Todos os comandos devem estar alinhados por tabulação ao identificador ao qual pertencem (após o espaço que segue o identificador). Ativar a opção smart tab do Editor Properties do delphi.

Exceto para os primeiros comandos dentro de um procedimento ou dentro de um REPEAT ou TRY, estes devem estar alinhados à dois espaços após a primeira letra do identificador.

Em declarações e atribuições as "variáveis" têm que estar alinhada entre si, uma embaixo da outra sempre que formarem mais de uma linha.

var bCondicao1, bCondicao2, bCondicao3, bCondicao4, bCondicao5: Boolean; cTeste1, cTeste11: string; begin  
if bCondicao1 and bCondicao2 and bCondicao3 then begin cTeste1  := 'Sim'; cTeste11 := 'Ok';
end else if bCondicao4 then begin cTeste1  := 'Não'; cTeste11 := 'Erro';
end;   end;

Identificadores ​

Todo identificador with, for, while, if ou else, deve conter um begin e um end, mesmo quando houver apenas uma linha de instrução. Exceto nos casos em que toda a instrução, incluindo o identificador, possa ser disposto em uma única linha.

Exemplos:

if Not(bCondicao) then Exit;

if Not(bCondicao) then begin ShowMessage('Exemplo de if usando begin-end'); end;

Se várias condições estiverem sendo testadas em uma instrução if, as condições deverão ser organizadas da esquerda para a direita na ordem de intensidade de cálculos, da menor para a maior. Isso permite que o seu código aproveite a lógica de avaliação Boolean de curto circuito embutida no computador. Por exemplo: Se a Condição1 for mais rápida do que a condição2, e a condição2 for mais rápida que a condição3, então a instrução if deverá ser construída da seguinte forma:

if condição1 and condição2 and condição3 then

Identificador CASE ​

Os casos individuais em uma instrução case deverão ser ordenados pela constante de caso, seja numérica ou alfabeticamente.

case ListaDeCasos of Caso1: begin // Várias instruções; end; Caso2: // Uma Instrução; end;

Comandos de interrupção devem estar localizados no início ou fim

Geralmente quando desejamos incluir novos recursos em uma rotina, o fizemos no final. Dessa forma, não corremos o risco de prejudicar as instruções anteriores. Também não percorremos toda a rotina para saber como ela funciona em seus mínimos detalhes. Olhamos apenas no início, para saber onde começa, e no final, para saber onde incluir o novo recurso. No entanto, se no meio da rotina houverem comandos de interrupção, uma instrução incluída no final pode não ser executada.

Os comandos Continue e Break, devem ser usados no início ou fim de um laço, nunca no meio.

O comando Exit deve ser usado no início ou fim de uma função ou procedimento.

Identificador WITH ​

Devemos evitar o uso do WITH.
Usar FieldByName ao invés da propriedade Text ou Caption.
Em componentes DataWare usar FieldByName relacionado, e não a propriedade Text ou caption.

Uso de Comentários ​

Evitar comentários desnecessários, muitos comentários dificultam a interpretação do fonte.

O símbolo "{}" deve ser sempre usado quando a intenção é esconder uma ou mais linhas de programação do compilador. O símbolo "//" deve ser usado para comentários. Não usar comentário quando houver, por exemplo: um ShowMessage, que por si só, deixa bem claro a funcionalidade da rotina, ou uma variável com um nome bem definido, ou funções comuns do Delphi.

Organizar o projeto ​

Os componentes não visuais apesar de não serem vistos em tempo de execução, em tempo de projeto devem estar alinhados uns aos outros.

Quanto às expressões de condição ​

Em expressões de condição a variável que cumprirá a condição deve vir antes do valor da condição. Exemplo: para somar a quantidade de clientes cujo estado seja igual a Santa Catarina na tabela de clientes usando um laço while, a variável que sofre a condição qr_Cliente.FieldByName('Uf').AsString deve vir antes da expressão "SC", o mesmo para a variável tb_Cliente.Eof que deve vir antes da constante False.

while (qr_ClienteCLUf.Value = 'SC') and (qr_Cliente.Eof = False) do begin iQtdCli := iQtdCli + 1;

qr_Cliente.Next;

end;

Quanto às expressões de atribuições longas ​

Quando um parênteses for aberto em uma linha e continuar na próxima, a linha seguinte, se possível, deve iniciar após a posição do parênteses aberto seguida de uma espaço. Da mesma forma, quando uma atribuição ultrapassar uma linha, a próxima linha deve continuar abaixo do primeiro caracter após o sinal de atribuição ":=" da linha anterior. Se a atribuição começar na linha posterior, a endentação deve ser de três espaços: Exemplo:

iIdadeEmDias := ((iAnoNascimento * 366) + (iMesNascimento*30) +

iDiaNascimento)-((iAnoAtual*366)+(iMesAtual*30) +iDiaAtual);

cMensagem := 'Mensagem para demonstrar a posição da próxima linha quando '+

'uma linha apenas não for o suficiente';

Devemos ser Óbvios ​

Alguns programadores, por puro exibicionismo, preferem confiar em seus conhecimentos técnicos a se sujeitar à simplicidade do óbvio. Tudo para que outros programadores tenham dificuldades em compreender a sua brilhante lógica e digam: "explique-me esta tua lógica porque só uma pessoa genial como você é capaz de compreende-la". Tolice, melhor programador é aquele que consegue tornar um problema complexo em um problema simples, não o inverso.

Exemplo, a expressão:

iIdadeEmDia := (iAnoNas*366) + (iMesNas*30) + iDiaNas;

É a mesma que:

iIdadeEmDia := iAnoNas*366 + iMesNas*30 + iDiaNas;

Mas a primeira atribuição é mais óbvia, já que dispensa o conhecimento das precedências do Delphi.

Procurar sempre limpar a sujeira ​

As constantes mudanças no código fonte acabam gerando instruções ou variáveis perdidas, sem finalidades. Devemos sempre procurar limpar a sujeira, arrumar a bagunça para que o código fonte não fique com a aparência de pano remendado.

Mensagens dentro de um exception ​

Mensagem dentro de um exception devem conter como última linha, o erro original que disparou a exceção: #13+#10+E.Message.

Evitar erros e facilitar detecção de erros ​

Sempre que for atualizar uma coluna de registros usar DisableControls.

Dentro de procedimentos genéricos use a função ControlsDisabled para certificar-se que o DataSet não esteja desabilitado. Neste caso não deveremos usar DisableControls e EnableControls.

Disablecontrols e EnableControls devem estar sempre dentro de um código protegido. TRY ... FINALLY.

Não usar real, usar sempre double.

Propriedades ou métodos do form colocar self. Ex: Self.Close.

Evitar ter que converter strings para valores reais.

Sempre que construir um form novo, lembrar que ele pode ser redimensionado. E os componentes devem se ajustar para qualquer tamanho de tela.

Evitar excluir linhas de programação. Ao invés disso devemos comentar, colocando o identificador do nome, a data e o motivo (ou número da tarefa).

Qualquer alteração nos fontes devemos marcá-los com um identificador do nome, o número da tarefa no WorkFlow ou em casos específicos, uma descrição do motivo.

SQLs em tempo de execução devem respeitar os padrões de instrução SQL.

Eliminar IFs desnecessários ​

Em muitos casos podemos eliminar IFs utilizando vetores ou matrizes. O exemplo a seguir mostra uma solução utilizando-se de "IFs" para contar de 1 à 3 e mostrar por extenso:

var i:Byte; begin   for i:=1 to 3 do begin if i=1 then ShowMessage('Um'); if i=2 then ShowMessage('Dois'); if i=3 then ShowMessage('Três'); end;   end;

Substituindo "IFs" por vetor:

var aNroExt:Array [1..3] of String; i:Byte; begin   aNroExt[1] := 'Um'; aNroExt[2] := 'Dois'; aNroExt[3] := 'Três';   for i:=1 to 3 do ShowMessage(aNroExt[I]);

Arquivos de Exportação e Importação ​

Sempre que for necessário criar um arquivo de exportação, salvar o número da versão de layout.

Valores Booleanos ​

Devemos sempre nos lembrar que: True = Verdadeiro (Correto, Certo), False = Falso (Errado, Negativo, Com Problema)

Exemplo: A função CheckLimiteCredito deve retornar "true" se o crédito estiver dentro do limite, e "false" se estiver fora dos limites.

Outro exemplo:

Se eOpcao = b, gr_1 será visível ou invisível?

type TOpcao = (a,b,c,d,e); var eOpcao:TOpcao;

Incorreto:

gd_1.Visible := True; gd_2.Visible := True; if eOpcao = a then begin gd_1.Visible := False; end else begin gd_2.Visible := False; end;

Correto:

gd_1.Visible := False; gd_2.Visible := False; if eOpcao = a then begin gd_2.Visible := True; end else begin gd_1.Visible := True; end;

Finalização das alterações(Padrão de Descrição dos Commits) ​

No momento de subir(commitar) os fontes no git é importante que seja mantido um padrão no campo "Message". Isto facilita caso seja necessário encontrar o ticket que originou a alteração, e facilita no caso de merge e etc. Adotamos o seguinte padrão:

Projetos e Sustentação deve seguir este padrão:

GES-Número do chamado - Atividade executada Informações complementares;

Ex:

GES-2019078458 - PJ6306 Nota Técnica GRUPO G 2018.005 - Banco de Dados, criação de colunas e tratamentos no processo de Integração. Criação dos campos nas tabelas.

Referenciado por: Análise de Interfaces | Dicas Técnicas | Documentação em Fontes de Delphi | Estrutura de Pastas | Filosofias de Programação | Predefinição:Guia de programação | Padrões de Interface do Commerce | Padrões para uso de componentes em Delphi | Tutoriais para Implementações em Delphi |