
-FAMILY: Verdana">Dicas para Qualidade
Aprenda técnicas para melhorar as métricas de qualidade de código
No primeiro artigo desta série, veremos como nos livrar dos casos mais difíceis de anti-patterns de código: métodos com estruturas de controle muito longas
O leitor interessado em garantir a qualidade do seu código – e ainda pior, do código de grandes projetos integrados por muitos desenvolvedores – já deve ter ouvido falar de diversos critérios e ferramentas de validação de código-fonte. Nesta coluna, já cobrimos na Edição 36 (“Qualidade Aplicada”) as ferramentas Checkstyle e PMD, a primeira orientada à validação do estilo do código-fonte, a segunda um detector de “anti-patterns de programação” – que inclui desde práticas questionáveis até bugs
Nesse ponto muitos desenvolvedores desanimam: podemos concordar com a teoria e aprender a usar as ferramentas que apontam problemas de código, mas o que fazer em casos onde o “defeito” apontado parece não ter nenhuma solução razoável? A documentação das próprias ferramentas não ajuda: as mais bem documentadas chegam a descrever detalhadamente a lógica de cada validação, mas nenhuma que vi vai muito longe sugerindo soluções. Há muitos problemas cuja solução é óbvia (por exemplo, “não use atributos públicos” – basta torná-los private e criar getters e setters), mas outros nem tanto.
Neste artigo, veremos como eliminar um destes defeitos – ou nem cometê-lo – livrando seu projeto de uma avaliação ruim por processos de revisão de código manuais ou automatizados, e é claro, das conseqüências práticas do defeito, como dificuldade de manutenção.
Este é o início de uma série, mas é uma série diferente da maioria que temos publicado na Java Magazine. Primeiro, cada artigo será curto, focado num único “anti-pattern” de código (talvez dois ou mais, cuja solução seja muito simples). Segundo, todos os artigos serão independentes, não havendo necessidade de lê-los em seqüência.
Uma cascata de problemas
Um dos problemas mais comuns em código considerado de baixa qualidade é a presença de classes ou métodos muito grandes. Isso é indesejável porque, quanto maior um artefato (classe ou método), mais difícil compreendê-lo.
No artigo de métricas, os autores sugerem o uso de refactoring para quebrar classes ou métodos complexos em pedaços menores. Isso não é uma enganação: continuamos tendo a mesma complexidade total, mas esta é dividida em componentes mais simples. Cada componente individual é mais fácil de entender, porque contém menos código; e é mais fácil de testar, porque possui uma interface (número e complexidade de parâmetros e retorno) mais enxuta. No caso de refactoring de classes, criando novas classes auxiliares, também o estado dos objetos (atributos) é decomposto em grupos menores, aumentando o encapsulamento. É a mesma lógica que levou dos primórdios da programação – quando era comum aplicações inteiras serem codificadas numa só rotina – à programação estruturada, e desta, à Orientação a Objetos.
Porém, o que fazer com métodos que aparentemente não podem ser quebrados? Um dos casos mais comuns onde isso acontece é métodos com longas estruturas de decisão.
Listagem 1. Método calculaBonus() original, com estrutura de if em cascata.
public class Pagamentos {
public double calculaSalario (Funcionario f) {
return f.getSalarioBase() + calculaBonus(f);
}
private double calculaBonus (Funcionario f) {
if (f instanceof Diretor)
...