[Delphi] Breves dicas de Clean Code

Olá, leitores!
Há alguns meses, tive a oportunidade de assumir a correção das avaliações técnicas dos candidatos para Delphi na DB1 Group. O pessoal manda muito bem nos projetos!
No entanto, eventualmente encontro algumas codificações que, apesar de simples, podem ser melhoradas para resultar em um código mais clean. Confira!

Para muitos de vocês, as dicas abaixo serão meramente óbvias. Mesmo assim, faço questão de publicá-las aqui para fomentar cada vez mais as práticas de Clean Code. A intenção é colaborar, aos poucos, para a eliminação daqueles códigos que nos fazem torcer o nariz. 🙂

1) Resultados de condições booleanas

Um erro que às vezes encontro nas codificações envolve condições booleanas para atribuir resultados:

Este código pode ser substituído por apenas uma linha, facilitando até mesmo a interpretação da regra:

2) Negando a negação

Seja cauteloso no código para evitar condições que neguem negações:

Ao ler este código, pensamos: “Espere aí… se a função avalia se o cliente não está ativo, mas tem um not… então a condição verifica se ele está ativo?!”. Sim! E se este é o caso, vale muito a pena reescrevê-lo:

3) Concatenação de strings

É comum encontramos códigos como esse:

Observe que há 4 operadores de adição (+) utilizados para concatenar o texto, dificultando a visualização do texto como um todo. Na verdade, essa dificuldade é exponencial. Quanto mais operadores existirem, mais difícil será a visualização.

Para evitar o uso demasiado deste operador, basta recorrer à função Format nativa do Delphi, que permite declarar um texto com parâmetros e preenchê-los em um array:

4) Incrementar/Decrementar valores

Podemos incrementar ou decrementar uma variável dessa forma:

Contudo, considere a utilização das funções Inc e Dec, presentes no Delphi desde suas primeiras versões:

Aproveitando o tópico, muitos desenvolvedores têm o hábito de decrementar a segunda expressão de uma instrução For, por exemplo, para acessar os itens de uma lista:

Para evitar o “- 1”, que transmite uma sensação de número mágico, podemos utilizar o Pred:

Lembrando, claro, que existe o For-In desde a versão 2005 do Delphi:

5) Condições if aninhadas

Algumas vezes tendemos a trabalhar sempre com resultados verdadeiros em condições if. Veja este exemplo:

Essas condições aninhadas exigem a construção de uma “sequência lógica” em nossa memória para que possamos acompanhar o fluxo de execução. Entretanto, em certo ponto, naturalmente nos perdemos em meio à tantas condições, que se agravam ainda mais quando há fluxos alternativos (else).

Para “limpar” este código, podemos empregar condições de guarda com instruções de saída do método:

6) Chamadas repetidas com longos namespaces

Já encontrei códigos parecidos com este:

Para a leitura, é muito mais cômodo atribuir parte dos namespaces à uma variável e utilizá-la nas instruções seguintes:

No entanto, deixo uma observação: se as chamadas aos métodos exige acesso a toda essa sequência de namespaces, talvez seja uma boa hora de rever a arquitetura!

7) Tipos de dados inadequados

No Delphi, assim como em outras linguagens, cada tipo de dado usa uma porção de espaço na memória. Por exemplo, o tipo integer ocupa 4 bytes devido à sua dimensão, que pode atingir um valor de até pouco mais de 2 bilhões. Pensando assim, você acha que faria sentido criar uma variável que se refere a um dia do mês como integer?

Bom, sabemos que o valor máximo para o dia do mês é 31. Se o tipo integer passa de 2 bilhões, estamos alocando um espaço que jamais será utilizado. Podemos, então, substituir o integer pelo byte.

Há quem diga que os computadores atuais possuem alta capacidade de memória e que detalhes como o tipo ideal de dado podem ser ignorados. Concordo. Porém, lembre-se que a sua aplicação declara, preenche e acessa variáveis a todo momento, incontáveis vezes por dia.

Acredito que, quanto menos memória uma aplicação exige durante a sua execução, melhor será o aproveitamento de recursos do sistema operacional para outras tarefas, certo? 🙂

Para mais informações sobre o limite de valores de cada tipo, acesse este link do DocWiki.

8) Atribuição de uma nova condição no filtro do DataSet

Alguns desenvolvedores assumem que é necessário desabilitar a propriedade Filtered do DataSet para atribuir um novo valor à propriedade Filter, como no código abaixo:

Podem ficar tranquilos, pessoal. A propriedade Filtered, uma vez habilitada, aplica as novas definições de filtro automaticamente, portanto, não é necessário desabilitá-lo para cada nova atribuição:

9) Estado de inserção ou edição

É comum a necessidade de identificar se um DataSet está em estado de inserção (após um Append/Insert) ou em estado de edição (após um Edit):

Existe uma instrução mais simples para essa verificação, que consiste na comparação apenas com dsEditModes:

Explicando: dsEditModes equivale a dsInsert, dsEdit e dsSetKey.

10) Inserção de registros em um DataSet

Considere um DataSet com 3 campos. Para inserir registros, você provavelmente escreveria o código abaixo, certo?

O código não está incorreto, mas pode ser melhorado! Com um método (pouco conhecido) chamado AppendRecord, pode-se reduzir essas cinco linhas em apenas uma:

Essa última é boa, hein? 🙂

 

Fico por aqui, pessoal. Foi apenas um artigo breve e informativo.
Volto em breve com o primeiro artigo do SOLID. Abraço!


 

André Celestino