Seu repositório sabe tudo sobre seu projeto!
Até então, eu já falei bastante sobre códigos fedidos e métricas de código aqui no blog, como por exemplo nos posts sobre complexidade ciclomática, acoplamento, coesão, asserts em testes, e outros maus cheiros. Todos eles até agora, se baseiam no código. E faz todo sentido, claro, afinal, como achar um arquivo Java problemático, sem olhar o código Java desse arquivo?
Mas temos um outro lugar bastante interessante, onde podemos procurar por coisas estranhas em nosso projeto. E esse lugar é o repositório de código que guardamos nosso projeto! Por exemplo, o Git. Afinal, tudo que você faz em seus arquivos, todas as pequenas modificações que acontecem ao longo do tempo, são salvas lá.
Pensa comigo: um arquivo que foi modificado em 25% de todos os commits do projeto parece estranho, não!? E o arquivo que o desenvolvedor escreve "corrigi um bug" na mensagem, toda vez que é committado? E o arquivo que já teve muitas linhas adicionadas e removidas, o que significa?
E por aí vai! E o mais legal é que basta minerar um pouco do repositório para extrair tudo isso. Essas métricas são conhecidas por change metrics, ou social metrics. Exemplos de informações que podemos extrair de repositórios:
- Contar o número de vezes que o arquivo foi modificado
- A quantidade de linhas já alteradas ao longo do tempo
- O número de desenvolvedores diferentes que já tocaram nele
- Quantos arquivos em média são modificados sempre junto com ele
- Quantas vezes o desenvolvedor disse que fez uma "refatoração" nele
- Quantas vezes o desenvolvedor disse que "corrigiu um bug" nele
Essas informações podem nos ajudar a descobrir arquivos que merecem mais atenção que outros. Veja, por exemplo, as informações que conseguimos extrair do VRaptor 4 nessa planilha no Google Docs. Se ordenarmos por "revisions", ou seja, número de revisões que um arquivo já teve, vemos que o VRaptor.java está em primeiro lugar, seguido do GenericContainerTest.java, AspectStyleInterceptorHandlerTest.java e GsonJSONSerializationTest.java. Ou seja, a classe principal do VRaptor, bem como seus testes são frequentemente modificados.
Se ordenarmos por "bugfixes", e olharmos as primeiras posições, vemos que o VRaptor.java também aparece lá. Ou seja, sempre que há uma correção de bug, alguém mexe lá também. Se pularmos as próximas que são testes, encontramos a LinkToHandler.java. Será que devemos nos preocupar com ela? Se ordenarmos por "churn", ou seja, a quantidade de linhas adicionadas e removidas na história do arquivo, temos IogiParametersProviderTest.java com 2188 linhas. Por que essa classe muda tanto?
Esses dados não nos indicam classes problemáticas, mas nos ajudam a mostrar classes ... digamos, diferentes. E é sempre legal descobrir o que foge do padrão, não é mesmo?
Esses dados também devem ser interpretados com contexto. Por exemplo, para descobrir "bugfixes", procurei por commits com a palavra "fix" no meio. Pelo baixo número de bugs (já passei por sistemas com valores muito maiores), os desenvolvedores podem não fazer uso dessa nomenclatura, e por consequência, esse número pode ser longe da realidade. Mas nada impede você de modificar o algoritmo para o seu projeto em específico.
Se você quer calcular isso em seu projeto Git, você pode usar um projeto meu, de código aberto para isso. Ele se chama change-metrics, e tem uma release pronta com o jar. Ele gera um CSV idêntico ao que mostrei do VRaptor. As instruções de uso estão no próprio README do projeto. Se você quer fazer outros tipos de análises mais complicadas em seu repositório, pense em usar o MetricMiner, um framework que criei para minerar repositórios Git.
Se gostou da ideia e quer ler mais sobre estudos malucos que as pessoas fazem com isso, veja conferências como a MSR, ICSME e SANER, e descubra da onde saiu o meu tweet sobre o quanto cada framework de persistência, como Hibernate, JPA, etc, sobrevivem em projetos Java.
No Alura, temos muitos cursos que ajudam você a combater esses maus cheiros de código, como é o caso do nosso curso de SOLID ou o curso de Design Patterns.