Medidor de métricas?

Galera, alguma recomendação de ferramenta ou plug-in pro Eclipse que gere um relatório de métricas?

Preciso de métricas do tipo SPM (statements por método), SPC (statements por classe), CPS (comentários por statement) e, e o bicho souber fazer algo do tipo detectar copy’n’paste, joia :smiley:

Olá

JDepend, Metrics e mais alguns em: Plugins for category Source Code Analyzer

Depois nos diga se algum serviu.

[]s
Luca

NHAM! :smiley:

Beleza, digo sim… :wink:

Aproveitando, algum toque, truque, dica ou paper com menos de 2 páginas sobre análise de código? Nao tou querendo fazer FPA, pq eu sou soh um ser humano, e eu já estou entrando em overdose de cafeína antes mesmo de começar (e, pra piorar, ainda tou com sono…). Algo bem rule-of-thumb, mesmo. Quando vcs consideram um método bom, e quando ele se torna lixo? Qual a linha divisória? :smiley:

PS: se estiver dificil de responder, e vcs preferirem discutir sobre a origem do universo ou religião, tudo bem tb :lol:

Olá

Antigamente, bem antigamente ainda no tempo da programação estruturada, a gente precisava imprimir as rotinas e quando elas ficavam com muitas páginas, eram difíceis de ler. Então algumas empresas adotavam uma regra radical: fora o trecho de definição de variáveis, o tamanho limite de uma rotina devia ser de 60 linhas. Assim as rotinas muito longas eram divididas em partes para facilitar a leitura.

Hoje com OO o objetivo passou a ser a questão da especialização. Os métodos devem fazer uma coisa só. Mesmo assim alguns métodos podem ficar meio grandinhos. Mas o que é grande e complexo para um pode não ser para outro.

Para mim o método fica um lixo quando está grande e confuso. Se este é seu caso e tem tempo para refatorar, refine o grau de especialização passando algumas partes centrais para outros métodos privados.

[]s
Luca

Bons conselhos, Luca! Valeu :slight_smile:

Vou aproveitar e acabar respondendo minha propria pergunta aqui. Uma regrinha bem facil que eu acabei arrumando é a de “nao comente, extraia um método”. Vou tentar dar um exemplo:

[code]public class Node {

private List childNodes = new ArrayList();

public int appendChild(Node child) {
childNodes.add(child);

 // retornar o tamanho da lista, que eh a posicao atual do child node
 return childNodes.size()-1;

}

public Node removeChild(int index) {
return childNodes.remove(index);
}
}[/code]

Refatorando uma classe dessas eu provavelmente acabaria implementando um outro metodo, assim:

private int getLastInsertedNodeIndex() { childNodes.size() - 1; }

E, claro, removeria o comentario, ja que agora o codigo se tornaria auto-explicativo.

Claro, esse eh um exemplo meio extremo, mas acho que deu pra passar a ideia, que eh a de quebrar o codigo ao maximo possivel, em rotininhas com nomes mais compreensiveis. Pq, nesse caso, vc nao quer saber o tamanho da lista, vc quer saber o indice do ultimo Node inserido (last inserted node index). :wink:

Toda cuidado para não extrair common-subexpressions demais.

Eu acredito que documentação dentro da função é mais para notas de desenvolvimento que para documentação, coisas como TODO, FIXME, etc são legais dentro de código que ainda está sofrendo muita modificação.

Mas tem muitos casos onde a documentação é indispensavel, nomalmente quando envolve gerenciamento de recursos e métodos/atributos não públicos:

   protected final Object lock = new Object();
  /**acessar somente depois de sincronizar em lock*/
  protected int count;
   /**Chamar somente quando estiver no estado XX e com o arquivo aberto*/
   private void readRegister() {
     ...
   }

As vezes não da para traduzir isso na assinatura ou ficar verificando. Sem falar que nomes com mais de 30 caractéres é sacanagem…

Olá

Sobre o JDepend, ferramenta free para examinar seu código e verificar impacto de eventuais mudanças: Managing Your Dependencies with JDepend

[list]
. . .
JDepend is an open source software program available for download at http://www.clarkware.com. The download includes the source code, JUnit test cases, documentation, pre-build .jar files, an ANT build script, and a sample application for testing purposes. The online documentation covers all of the features available for setting up, configuring, and running JDepend
. . .
Once you understand the JDepend metrics, you may want to automate their collection within your normal build and release cycle. Fortunately, there are optional Ant tasks for doing just that. If you are using Ant 1.5, you can use an XSL stylesheet to transform your JDepend XML output into an HTML report. These reports can be used as a regular part of your quality or metrics program. Turbine and Maven are two projects utilizing this feature.
[/list]

Lá estão algumas métricas que se podem obter com o JDepend:

[list]
CC Concrete Classes
The number of concrete classes in this package.

AC Abstract Classes
The number of abstract classes or interfaces in this package.

Ca Afferent Couplings
The number of packages that depend on classes in this package. Answers the question “How will changes to me impact the rest of the project?”

Ce Efferent Couplings
The number of other packages that classes in this package depend upon. Answers the question “How sensitive am I to changes in other packages in the project?”

A Abstractness
Ratio (0.0-1.0) of Abstract Classes (and interfaces) in this package. AC/(CC+AC)

I Instability
Ratio (0.0-1.0) of Efferent Coupling to Total Coupling (Ce/(Ce+Ca)).

D Distance from Main Sequence
The perpendicular distance of a package from the idealized line A+I=1. Answers the question “How balanced am I in terms of Abstractness and Instability?” The range of this metric is 0 to 1, with D=0 indicating a package that is coincident with the main sequence (balanced) and D=1 indicating a package that is as far from the main sequence as possible (unbalanced).
[/list]

[]s
Luca

Tem mais uma coisa boa sobre o JDepend: tem task pro Ant.

eu costumo achar um método um lixo quando ele começa a ficar assim:

public void saveWorkspace(Workspace ws) {
   
   // save the preferences
   Properties p = ws.getPreferences();
   FileOutputStream fos = ...
   p.store(fos);

   // save the buffer list
   Iterator it = ws.getBuffers().iterator();
   while (it.hasNext()) {
      ...
   }

   // clear the buffer list
   ws.getBuffers().clear();
}

Esse é o exemplo mais clássico que existe de extract method. Mas eu não removo os comentários:

public void saveWorkspace(Workspace ws) {
   // save the preferences
   savePreferences(ws.getPreferences());
   // save the buffer list
   saveBuffers(ws.getBuffers());
}

Lógico que limpar os buffers foi pra outro lugar no meio do refactoring, pq não tem nada a ver com saveWorkspace.

Eu gosto de pensar assim:

:arrow: efeitos colaterais (como limpar os buffers quando vc salva o workspace) são ruins
:arrow: alguém um dia vai querer extender ou delegar pra essa classe. Vc tá permitindo polimorfismo? Vc tá permitindo que o cara extenda sua classe e altere um minúsculo pedacinho do funcionamento, mantendo o resto?

Com essas duas regrinhas vc não consegue mais escrever métodos imensos.

[]s