# 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.

<p class="callout warning">Deve-se evitar ao máximo realizar commits sem mensagem, principalmente em versões e no trunk.</p>

#### **Exemplos**

---

##### **Modelo de Mensagem**

<table border="1" id="bkmrk-caso-xxxxx%3A-descri%E3%A7%E3%A3" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 100%;">Caso XXXXX: Descrição do caso de acordo com o Mantis/Trello.

\- Mensagem descritiva e em poucas palavras do que foi alterado  
  
(Opcional) Desenvolvedor

</td></tr></tbody></table>

---

##### **Criação de branch**

<p class="callout info">Ao criar um branch, deve-se informar o número do caso e a sua descrição de acordo com o Mantis/Trello.</p>

<table border="1" id="bkmrk-caso-xxxxx%3A-descri%E3%A7%E3%A3-0" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 100%;">Caso XXXXX: Descrição do caso de acordo com o Mantis/Trello.

\- Criação do branch  
  
(Opcional) Desenvolvedor

</td></tr></tbody></table>

##### **Alterações** 

<p class="callout info">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.</p>

<table border="1" id="bkmrk-caso-xxxxx%3A-descri%E3%A7%E3%A3-1" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 100%;">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

</td></tr></tbody></table>

##### **Atualização de Branch**

<p class="callout info">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.</p>

<table border="1" id="bkmrk-%5Batualiza%E3%A7%E3%A3o-do-bran" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 100%;">\[Atualização do Branch\] Caso XXXXX: Descrição do caso de acordo com o Mantis/Trello.

  
(Opcional) Desenvolvedor

</td></tr></tbody></table>

# Documentação Interna

#### **Comentários** 

Segundo Robert C. Martin em Código Limpo: Habilidades Práticas do Agile Software,

> “O uso adequado de comentários é compensar nosso fracasso em nos expressar no código.”

Dessa maneira, o **uso de comentários no código deve ser evitado**, visto que, conforme o código passar por manutenção, a tendência é que o comentário fique desatualizado e não condizente com o trecho de código à que se refere.

#### **Comentários que podem ser adicionados:**

##### **Comentários descritivos:**

```PASCAL
// INSS
if (DM_GERACAO.EventosSendoGerados.IndexOf('e301') <> -1) then
begin
	Código Referente ao INSS
end;
```

<p class="callout success">Comentários que complementam o entendimento de uma rotina, mas que não tentam explicar o que está sendo feito no trecho.</p>

---

#### **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 							*
****************************************************************}
```

<p class="callout danger">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.</p>

---

##### **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.
```

<p class="callout danger">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. </p>

---

##### **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;
```

<p class="callout danger">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.</p>

# Código Limpo

#### **Definição de Clean Code**

<span style="font-weight: 400;">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 (</span>*<span style="font-weight: 400;">clean code</span>*<span style="font-weight: 400;">) deve ser:</span>

- <span style="font-weight: 400;">Simples: fácil entendimento;</span>
- <span style="font-weight: 400;">Eficiente: realizar tudo o que foi proposto;</span>
- <span style="font-weight: 400;">Único: não realizar algo que outro trecho de código já faz;</span>
- <span style="font-weight: 400;">Direto: não dar voltas para chegar no resultado;</span>
- <span style="font-weight: 400;">Feito com atenção: o código deve ser sempre feito com preocupação e revisto depois de pronto;</span>

#### ***Bad Smells***

Em contra partida, também existem as *<span style="font-weight: 400;">Bad Smells</span>*<span style="font-weight: 400;">, 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 </span>*<span style="font-weight: 400;">bad smells</span>*<span style="font-weight: 400;">.</span>

##### **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;
```

<p class="callout info">Esse tipo de encadeamento pode ser facilmente substituído pela palavra reservada "and".</p>

```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;
```

<p class="callout info">O trecho acima pode ter sua estrutura facilitada com a utilização de um "case".</p>

```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**

<p class="callout danger">Situações com atribuições indiretas aparecem constantemente no código</p>

```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;
```

<p class="callout success">Basta uma pequena análise por parte do desenvolvedor para perceber que podem ser simplificadas</p>

```PASCAL
 LDeveIncrementar := (Q_Manut.FieldByName('DiasDireito').AsFloat <> 0);
```

```PASCAL
LTipo := RG_TipoCliente.ItemIndex;
```