# Boas práticas Parte decisiva em manter um código limpo e de fácil manutenção, as boas práticas são essenciais para trabalhar em equipe em qualquer projeto. Neste capítulo, se encontram sugestões e práticas adotadas para a manutenção do código e uso das ferramentas utilizadas durante todo o processo de desenvolvimento. # Versionamento ### **Mensagens de Versionamento** Ao realizar qualquer alteração que seja necessário realizar um commit, é importantíssimo adicionar uma mensagem que possa informar do que se trata aquela alteração. Essa mensagem deve ser breve e descritiva, explicando em poucas palavras o que foi alterado, de forma que, caso outro desenvolvedor necessite realizar uma busca pelo log de alterações, as mensagens possam servir de "filtro" para identificar o que é relevante para a sua consulta.
Deve-se evitar ao máximo realizar commits sem mensagem, principalmente em versões e no trunk.
#### **Exemplos** --- ##### **Modelo de Mensagem**Caso XXXXX: Descrição do caso de acordo com o Mantis/Trello. \- Mensagem descritiva e em poucas palavras do que foi alterado (Opcional) Desenvolvedor |
Ao criar um branch, deve-se informar o número do caso e a sua descrição de acordo com o Mantis/Trello.
Caso XXXXX: Descrição do caso de acordo com o Mantis/Trello. \- Criação do branch (Opcional) Desenvolvedor |
Ao realizar o commit de alterações, além do cabeçalho indicando o número do caso e a descrição, deve-se adicionar por tópico as alterações feitas naquele commit.
Caso XXXXX: Descrição do caso de acordo com o Mantis/Trello. \- Alterações na lógica da rotina CalcularSaldo. \- Correções no padrão de código aplicado. \- Criação da classe TGerador (Opcional) Desenvolvedor |
Ao realizar a atualização de um branch(Merge com Trunk) , deve-se adicionar a "tag" \[Atualização do Branch\] no início do cabeçalho, para que ao consultar o log de alterações, o desenvolvedor identifique prontamente quais revisões são referentes à atualizações do branch e quais não são.
\[Atualização do Branch\] Caso XXXXX: Descrição do caso de acordo com o Mantis/Trello. (Opcional) Desenvolvedor |
Comentários que complementam o entendimento de uma rotina, mas que não tentam explicar o que está sendo feito no trecho.
--- #### **Comentários que devem ser evitados/removidos:** ##### **Comentários no cabeçalho:** ```PASCAL {**************************************************************** * Módulo : ArqTeste * * Finalidade : Realizar a exportação de Notas Fiscais * * de Serviços para Prefeitura de São Paulo * * Data : 21/02/2000 * * Programador : Fulano da Silva Santos * ****************************************************************} ```Comentários utilizados como cabeçalho que descrevem o que a unit faz, a data de implementação e o programador responsável pela implementação apesar de serem descritivos, muitas vezes não são atualizados conforme o código passa por mudanças. Essas informações podem e devem ser encontradas nas mensagens de versionamento.
--- ##### **Comentários referentes à processos passados:** ```PASCAL // MIGRACAO // Caso a classe uClass.NumDocs seja utilizada em alguma unit // a diretiva referente ao arquivo uClass.NumDocs.inc deverá ser acrescentada. // Ex: Ver units FormPri e Backup, antes do nome da unit; // No arquivo uClass.NumDocs.inc deverá ser adicionada a diretiva referente ao // sistema ao qual a classe NumDocs foi adicionada. ```Comentários como esses não acrescentam informações no entendimento do código e acabam criando uma poluição visual na unit, de modo que, com o passar do tempo a tendência é que esse tipo de comentário seja automaticamente ignorado pelos desenvolvedores.
--- ##### **Código comentado:** ```PASCAL // if ((QMANUT.FieldByName('DiasDireito').AsFloat = 0) or // (SameText(Trim(QMANUT.FieldByName('DiasDireito').AsString), ''))) and // (MessageDialog.Show('Não foi informado os dias de Direito. Deseja Continuar?', // mtConfirmation, [mbYes, mbNo], 0) = mrNo) then // begin // QMANUT.FieldByName('DiasDireito').FocusControl; // Abort; // end; ```Códigos comentados geram confusões no código, além de poluir desnecessariamente a unit, dessa maneira códigos não devem ser comentados e sim removidos. Caso necessário, pode-se visitar o histórico de revisões para acompanhar as alterações do trecho.
# Código Limpo #### **Definição de Clean Code** A apresentação de um código claro e organizado não consiste apenas na convenção nomes, constantes, classes, variáveis, espaçamento etc.. Um código limpo (*clean code*) deve ser: - Simples: fácil entendimento; - Eficiente: realizar tudo o que foi proposto; - Único: não realizar algo que outro trecho de código já faz; - Direto: não dar voltas para chegar no resultado; - Feito com atenção: o código deve ser sempre feito com preocupação e revisto depois de pronto; #### ***Bad Smells*** Em contra partida, também existem as *Bad Smells*, que como sua tradução já sugere, é algo com cheiro ruim, e representa o código com práticas que não devem ser utilizadas. Essas práticas se devem aos códigos que fogem das características de um código limpo. Abaixo são demonstrados alguns exemplos de *bad smells*. ##### **Encadeamento de If's** ```PASCAL if (Q_Manut.FieldByName('DiasDireito').AsFloat = 0) then begin if (AnsiSameText(Trim(Q_Manut.FieldByName('DiasDireito').AsString), ''))) then begin if (MessageDialog.Show('Não foi informado os dias de Direito. Deseja' + 'Continuar?', mtConfirmation, [mbYes, mbNo], 0) = mrNo) then begin Q_Manut.FieldByName('DiasDireito').FocusControl; Abort; end; end; end; ```Esse tipo de encadeamento pode ser facilmente substituído pela palavra reservada "and".
```PASCAL if (Q_Manut.FieldByName('DiasDireito').AsFloat = 0) and (AnsiSameText(Trim(Q_Manut.FieldByName('DiasDireito').AsString), ''))) and (MessageDialog.Show('Não foi informado os dias de Direito. Deseja' + 'Continuar?', mtConfirmation, [mbYes, mbNo], 0) = mrNo) then begin Q_Manut.FieldByName('DiasDireito').FocusControl; Abort; end; ``` --- ##### **Excesso de if-else** ```PASCAL if (Q_Manut.FieldByName('DiasDireito').AsFloat = 0) then LTipo := 1 else if (Q_Manut.FieldByName('DiasDireito').AsFloat = 1) then LTipo := 2 else if (Q_Manut.FieldByName('DiasDireito').AsFloat = 2) then LTipo := 3 else if (Q_Manut.FieldByName('DiasDireito').AsFloat = 3) then LTipo := 5 else LTipo := 9; ```O trecho acima pode ter sua estrutura facilitada com a utilização de um "case".
```PASCAL case Q_Manut.FieldByName('DiasDireito').AsFloat of 0: LTipo := 1; 1: LTipo := 2; 2: LTipo := 3; 3: LTipo := 5; else LTipo := 9; end; ``` --- ##### **Atribuição Indireta**Situações com atribuições indiretas aparecem constantemente no código
```PASCAL if (Q_Manut.FieldByName('DiasDireito').AsFloat = 0) then LDeveIncrementar := False else LDeveIncrementar := True; ``` ```PASCAL if (RG_TipoCliente.ItemIndex = 0) then LTipo := 0 else (RG_TipoCliente.ItemIndex = 1) then LTipo := 1; ```Basta uma pequena análise por parte do desenvolvedor para perceber que podem ser simplificadas
```PASCAL LDeveIncrementar := (Q_Manut.FieldByName('DiasDireito').AsFloat <> 0); ``` ```PASCAL LTipo := RG_TipoCliente.ItemIndex; ```