Recentemente, houve uma discussão na lista do GURU-SC em relação a uso de patterns para satisfazer um nivel de score específico no Code Climate.
Para quem não conhece, o Code Climate é uma ferramenta para geração automática de métricas de “qualidade”. Apesar deles se intitularem uma ferramenta de Revisão de Código, não é isso que a ferramenta faz:
“Code review is systematic examination (often known as peer review) of computer source code. It is intended to find and fix mistakes overlooked in the initial development phase, improving both the overall quality of software and the developers’ skills. Reviews are done in various forms such as pair programming, informal walkthroughs, and formal inspections.” – Wikipedia
Sendo pragmático, pode-se considerar o objetivo de “melhorar as habilidades dos desenvolvedores” como um objetivo complementar de “melhorar a qualidade geral do software”. Qualidade tem um significado subjetivo que pode ser visto pela ótica da robustez (um software de qualidade é aquele que nunca falha), ou pela facilidade de dar manutenção (desacoplamento, Separation of Concerns, cobertura de código, uso correto dos recursos de orientação a objetos, etc).
Um segundo problema que o processo formal de revisão ataca, é o de identificar e corrigir falhas em estágio inicial de desenvolvimento, para evitar que o mesmo se propague e torne custoso a correção. O objetivo aqui é em reduzir o tempo total de desenvolvimento e reduzir custos.
Falando sobre o primeiro problema:
A teoria da computação nos garante que é computacionalmente impossível , gerar uma ferramenta que nos garanta que para qualquer aplicação informada, seja possível fazer uma análise para saber se a mesma é 100% livre de falhas. Isto é conhecido como Halting problem.
Sabendo que não é possível construir tal ferramenta, podemos tentar resolver por aproximação, criando uma ferramenta que ataque um nicho específico de aplicações, ou tentar outras abordagens que tenham um melhor custo benefício em casos genéricos.
As abordagens genéricas, sabendo-se que não é possível automatizar essa solução, atacam o problema através de mudanças no processo. Essas mudanças podem ser feitas de N maneiras distintas. As mais tradicionais vão pela linha do modelo de maturidade (entende-se aqui a adoção de CMMI, MPSBR, etc. e suas práticas).
Modelos de maturidade estão em baixa atualmente, devido em parte do sucesso do movimento ágil, e em partes devido a ascensão de linguagens mais dinâmicas e que utilizam paradigmas mais distintos.
Uso de métricas para auxiliar um processo de desenvolvimento ágil:
Uma das alternativas que se pensa no mundo ágil para tentar alcançcar o mesmo objetivo (produzir um software de qualidade, livre de falhas), é a utilização de métricas para “julgar” a qualidade, substituindo a revisão formal.
O problema das métricas é que elas indicam o “estado em que está”, mas não um “caminho para onde se quer chegar”. Tem um artigo muito bom de um dos criadores do Code Climate, que fala sobre as métricas utilizadas no Ruby, o significado delas e a motivação deles ao construir a ferramenta:
“…There’s a lot our code can tell us about the software development work we are doing. There will always be the need for our own judgement as to how our systems should be constructed, and where risky areas reside, but I hope I’ve shown you how metrics can be a great start to the conversation.”
A armadilha está na geração de um score. Se você parar para pensar, o score nada mais é do que uma formula, definida unilateralmente (chame aqui de “opinião” ou “convenção”), que uma empresa ou um grupo de pessoas dentro da mesma definiu.
Esse score leva em consideração regras que eles acreditam que refletem o que seria um código “bom”, do ponto de vista deles. Note que estamos falando sobre ponto de vista (pode-se considerar nesse contexto como um sinônimo pra opinião).
Algumas das métricas que compõem o score, possibilitam uma análise precisa sobre “bom” e “ruim” enquanto outras sugerem que seja definido um threshold, para que conclusões seja feitas. A idéia de se precisar definir um threshold, indica claramente que determinada solução não pode ser aplicada universalmente, e portanto ao usar dessa forma, estamos cometendo um grave equívoco.
Esse equívoco vai mais além. Ao marcar um código como “ruim” (aplicar uma nota B, C, D…), baseado em uma análise falha, tenta-se sugerir maneiras de refatorar o código para que a nota seja melhorada, e então considerar que aquele código é “bom”.
Se voltarmos a nossa análise inicial sobre o Halting problem, o erro básico aqui fica mais grigante.
O que fazer então?
Primeiramente, faça o que o próprio criador sugere, use o seu próprio julgamento e entenda quando alguma coisa deve ser mexida ou não, mas não faça apenas para subir a nota.
Existe um outro artigo que havia lido recentemente: “Automated code metrics: Why you shouldn’t care about thresholds”, que fala exatamente sobre essa questão, e sugere que você não deve escolher um score mínimo e transformar isso numa cruzada ignorante para manter o código dentro desses parâmetros a qualquer custo.
Uma forma de melhorar um pouco essa situação, seria que cada projeto pudesse customizar a forma como o score é gerado, podendo assim configurar os parâmetros que você considera coerentes para aquele projeto, tendo sempre a opção de “ignorar” (e registrar isso, de forma a corrigir o score) qualquer conclusão que a ferramenta realizar automaticamente para você.
Se você não está convencido de que este é o caminho correto, sugiro a leitura deste outro artigo do James Turner: “Process Kills Developers Passion”. No artigo ele ataca esse e outros “pecados” que são cometidos pela nossa indústria que nos desvia do caminho ideale nos distrai do nosso foco que é de fato produzir software livre de falhas e de qualidade.
(Eu pretendo escrever em um post futuro uma análise com a mesma óptica, sobre a utilização desenfreada de Design Patterns)