As métricas de software podem ajudá-lo a localizar elementos de design ocultos no seu código,
permitindo que eles aflorem em padrões idiomáticos. Este capítulo da Arquitetura Evolucionária e Design Emergente
mostra como o uso inteligente de métricas e visualizações permite a
descoberta de importantes elementos do código que são obscurecidos pela
complexidade acidental.
Uma das dificuldades do design emergente repousa na localização de
padrões idiomáticos e de outros elementos de design ocultos no código.
As métricas e visualizações são úteis para identificar partes
importantes do código e permitem que você as extraia como elementos de
design de primeira classe.
As duas métricas em que me concentrarei neste artigo são complexidade ciclomática e acoplamento aferente.
A complexidade ciclomática é a medida da complexidade relativa de um
método em relação a outro. O acoplamento aferente representa a contagem
de quantas classes diferentes usam a classe atual. Você conhecerá
algumas ferramentas para visualização e compreensão das métricas, e verá
como a combinação delas revela as características do design.
Um fator complicador das medições de complexidade ciclomática via
ferramentas Java é a unidade de trabalho. A complexidade ciclomática é
uma medição no nível do método, mas a unidade de trabalho na programação
Java é a classe. Consequentemente, essas medições geralmente chegam
como a soma ou a média da complexidade de todos os métodos em uma
classe. Ambas as medições são interessantes.
Por exemplo, é possível o cenário abaixo. Uma classe que apresenta
massivamente um método complexo (CC = 40), mas que também possui uma
grande quantidade de métodos muito pequenos (por exemplo, os pares de
métodos get/set comuns no código Java). Com uma ferramenta como o
JavaNCSS que informa a métrica como a soma de todos os métodos, a complexidade
ciclomática será um número alto para toda a classe.
Se você usar uma
ferramenta do tipo Cobertura, que informa a complexidade ciclomática
como uma média da classe esta não parecerá mais tão má, pois a
inundação de métodos simples amortizará o efeito causado por esse método
altamente complexo. Em face dessa incompatibilidade de unidade de
trabalho, o bom senso diz que, ao calcular a complexidade ciclomática,
tanto a soma total quanto a média das medições devem ser examinadas. Se
você considerá-las independentemente, o ruído poderá impregnar os
resultados. O uso de ambos os números esvazia essa possibilidade.
As outras métricas de interesse para o design são os dois números de acoplamento: acoplamento eferente e aferente.
O acoplamento eferente mede o número de classes às quais a classe atual
faz referência. É fácil de determinar por uma inspeção simples: abra a
classe em questão e conte as referências (nos campos e parâmetros) a
outras classes. O acoplamento aferente é mais difícil de determinar e
muito mais valioso. Significa quantas classes diferentes usam a classe
atual.
É possível usar a linha de comando fu para determinar isso ou
recorrer a uma das muitas ferramentas que compreendem essa métrica. Um a
delas é o ckjm, uma ferramenta de código livre para execução do
conjunto de métricas orientadas a objeto de Chidamber e Kemerer.
Embora sua preparação e execução sejam um pouco complicadas, ela
fornece a complexidade ciclomática (informada como a soma da
complexidade ciclomática de todos os métodos de uma classe) e os números
dos acoplamentos eferentes e aferentes.
Depois de ter esses números em mãos, o que eles significam,
principalmente em termos de design?
Os números gerados como métrica fornecem uma dimensão única das
informações sobre o seu código, no
entanto, os números em si, frequentemente, não significam grande coisa.
É
possível gerar informações
úteis a partir das métricas de dois modos. Um deles, é examinar como
determinado valor se altera no decorrer do tempo e nas principais
tendências. O outro é combinar métricas para enriquecer a densidade das
informações (essa é a abordagem que mostrarei mais tarde neste artigo).
Métricas de software versus métricas físicas
Em software, uma métrica significa aplicar uma medição de objetivo a
artefatos de desenvolvimento a fim de determinar características bem
específicas.
Diferentes da métrica física (por exemplo, uma régua), a maioria das
métricas de software não refletem nenhuma característica no mundo real.
Um número de complexidade ciclomática (por exemplo, 5) não tem nenhuma
unidade de medida e não diz nada sobre qualquer propriedade física do
código. Esse número faz sentido apenas quando comparado à complexidade
ciclomática de outro código.
Métricas e design
Eu tenho torturado a base de códigos do Struts nos artigos
desta série não por ter alguma coisa contra o Struts, mas porque ele é
um projeto de código livre muito conhecido. Acredite-me: você pode
encontrar características de design indesejáveis na maioria do código
disponível no mundo! Como já comecei com o Struts, permanecerei com ele
para ilustrar meus pontos.
A saída do ckjm é texto, que pode ser convertido para XML (e para outros
formatos, depois de diversas transformações com XSLT). A Figura 1
apresenta a combinação de várias métricas do ckjm, onde WMC (Weight Methods per Class) é a soma da complexidade ciclomática dos métodos da classe e Ca é o acoplamento aferente:
Figura 1. Resultados das métricas do ckjm em forma de tabela

A Figura 2 mostra a mesma tabela, classificada por WMC:
Figura 2. Métricas do ckjm, classificadas por WMC

Apenas olhando esse resultado, podemos dizer que DoubleListUIBean
é a classe mais complexa na base de códigos do Struts. Isso sugere que
ela é uma boa candidata para ser refatorada para remover um pouco da sua
complexidade e tentar localizar padrões repetitivos e abstratos. No
entanto, o número WMC não diz se o investimento na refatoração dessa
classe, para melhorar seu design, será um bom uso do tempo. Observe que o
Ca da classe é 3. Ou seja, ela é utilizada apenas por três classes
diferentes, o que sugere que não vale a pena investir muito tempo para
melhorar seu design.
A Figura 3 apresenta os mesmos resultados do ckjm, agora classificados por Ca:
Figura 3. Resultados do ckjm, classificados por acoplamento aferente

Essa visualização combinada mostra que a classe mais utilizada no Struts é Component (o que não é nenhuma surpresa, já que o Struts é uma estrutura da Web). Embora Component
não seja tão complexa, ela é usada por 177 classes diferentes, o que a
torna uma boa candidata para aprimoramentos de design. Tornar o design
de Component melhor repercute sobre um grande número de outras classes.
A combinação de WMC e Ca é o melhor modo para interpretar a perspectiva oferecida na Figura 3.
Ela informa o que é mais importante e o que é mais complexo na base de
código, em uma única visualização.
Se você chegou à base de códigos sem
nenhum conhecimento anterior, essa visão oferece insights sobre onde
seus esforços produzirão potencialmente melhores resultados. Embora não
seja infalível, agora você tem mais informações sobre a base de códigos
do que conseguiria derivar simplesmente examinando resmas de código.
As métricas numéricas fornecem insight sobre o código, mas elas
subsistem em um nível extremamente baixo, fornecendo informações sobre
classes específicas, sem contribuir muito para a aquisição de uma visão
holística de uma base de códigos. Há muita ferramentas disponíveis agora
para elevar as métricas ao próximo nível por meio de visualizações.
Visualizações de métricas
Esse recurso fornece visualizações alternativas de dimensões
específicas, tanto individualmente quanto agregando várias dimensões. A
comunidade do Smalltalk criou um número imenso de visualizações de
métricas (incluindo uma plataforma, denominada Moose, para ativar esses
tipos de visualizações; ao final do artigo consulte mais em Recursos). Muitas das técnicas de métricas desenvolvidas por essa comunidade migraram para a programação do Java.
O iPlasma e os padrões de mercado
Algumas das questões comuns relativas à complexidade ciclomática são
“Como comparar meu código ao de outros?” e “Qual é a quantidade ideal
para determinada classe?” O projeto do iPlasma responde a essas questões.
O iPlasma é uma plataforma, criada como um projeto em uma universidade
na Romênia, para avaliação da qualidade do design orientado a objeto.
Ele gera uma pirâmide e apresenta as principais métricas do projeto e a
comparação dessas aos valores padrão do mercado.
Ao executar o iPlasma, você aponta para um diretório de códigos de
origem e, depois de algum agito, produz uma pirâmide de métricas como a
ilustrada na Figura 4 que se baseia na base de códigos do Struts 2.0.11:
Figura 4. Pirâmide de métricas do iPlasma

Essa pirâmide estará cheia de informações, assim que você começar a
compreendê-la. Cada linha
tem uma porcentagem colorida derivada da proporção do número nessa linha
em relação ao número abaixo dele. A Tabela 1 mostra o que os números
indicam, de cima para baixo:
Tabela 1. Compreendendo a pirâmide do iPlasma
| Código | Descrição |
|---|---|
| NDD | Número de descendentes diretos |
| HIT | Altura da árvore de hierarquia |
| NOP | Número de pacotes |
| NOC | Número de classes |
| NOM | Número de métodos |
| LOC | Linhas de código |
| CYCLO | Complexidade ciclomática |
| CALL | Chamadas por método |
| FOUT | Fan out (número de outros métodos chamados por determinado método |
Os números indicam as proporções; as cores indicam onde as proporções se encaixam no faixa de valores padrão do mercado (derivados dos inúmeros projetos de código livre). As proporções podem ser verde (dentro do intervalo), azul (abaixo do intervalo) ou vermelho (acima do intervalo).
Para a base de códigos do Struts, NDD e CYCLO estão fora do padrão de mercado, e LOC e NOM estão abaixo. Os intervalos usados são exibidos na Tabela 2:
Tabela 2. Valores padrão de mercado para as métricas do iPlasma
| Baixo | Médio | Alto | |
|---|---|---|---|
| CYCLO / Linha | 0.16 | 0.20 | 0.24 |
| LOC / método | 7 | 10 | 13 |
| NOM / classe | 4 | 7 | 10 |
| NOC / pacote | 6 | 17 | 26 |
| CALLS / método | 2.01 | 2.62 | 3.20 |
| FANOUT / chamada | 0.56 | 0.62 | 0.68 |
O iPlasma também gera conselhos com base na pirâmide, que são mostrados na exibição do iPlasma imediatamente abaixo da pirâmide. A Figura 5 mostra o conselho para o Struts:
Figura 5. Conselho do iPlasma

Os números que o iPlasma gera servem para dois propósitos. Primeiro,
eles permitem que você compare a sua base de códigos ao de outros, e com
várias dimensões. Segundo, esses números indicam os lugares onde você
pode querer expandir seus esforços para melhorar a higiene e o design do
código.
Por exemplo, no caso do Struts, o iPlasma indica que a
profundidade da árvore de hierarquia é muito grande e que os métodos
tendem a ser muitos complexos. Contudo, você deve compreender esses
números no contexto. Uma estrutura da Web como o Struts tenderá a ter
uma hierarquia muito elaborada, o que significa que o número NDD
provavelmente não causa preocupação. O número CC, no entanto, não tem
nada a ver com o contexto ele está muito alto e indica cheiro de
design no nível do método.
Para fins de comparação, a Figura 6 mostra uma pirâmide do iPlasma para o
projeto Vuze, um BitTorrent Client escrito na linguagem Java:
Figura 6. Pirâmide do iPlasma para o Vuze
O Vuze é um projeto de grande porte (mais de 500.000 linhas de código),
com problemas de design potencial quanto à profundidade da árvore de
hierarquia, ao número de métodos em cada classe, ao número de linhas do
código por método e ao número de chamadas por método.
Dependências
O design emergente requer visibilidade em relacionamentos e outras
abstrações de alto nível no seu código. Tente perceber esses conceitos
de alto nível nas chamadas do código de origem tendo em mente aquela
famosa parábola dos cegos que tentavam compreender um elefante apenas
pelo tato. Cada parte do elefante se parece com alguma coisa diferente,
no entanto, o tato é muito localizado para permitir uma visão holística.
A determinação das dependências entre classes e objetos sofre do mesmo
tipo de problema de localização. Ferramentas como o iPlasma permitem que
você consulte um resumo das características gerais do código, no
entanto, não informam os pontos específicos que devem ser investigados.
Felizmente, outras ferramentas podem ajudá-lo a ver o elefante de
diferentes prismas.
A comunidade do Smalltalk criou uma ferramenta denominada CodeCrawle,
baseada na plataforma Moose, que oferece uma representação gráfica do
código, com dimensões para tamanho da classe, comprimento do método e
algumas outras métricas. É possível colocar o CodeCrawler para trabalhar
com o código Java, mas isso é temerário. Felizmente, você não precisa
lutar essa batalha porque o projeto X-Ray já venceu a guerra.
O X-Ray é um plug-in do Eclipse que gera várias visualizações úteis para
ser ter a visão da
estrutura geral do código, incluindo visualizações de setores circulares
das dependências entre classes, conforme ilustrado para o Struts na
Figura 7:
Figura 7. Visualizações do X-Ray das dependências de classes

Cada elemento, junto à borda do círculo, é uma classe e as linhas
indicam as dependências entre classes. A espessura da linha indica a
intensidade da dependência. Um clique na classe revela suas informações e
um clique duplo a abre no editor do Eclipse.
É óbvio que a visualização
inclui muito mais informações úteis. Felizmente, é possível aplicar um
zoom para ver as linhas individuais. As linhas em negrito indicam um
forte dependência entre as classes (acoplamento eferente), e talvez
signifiquem uma deficiência de projeto, quando o inter-relacionamento de
duas classes é excessivo.
O X-Ray também inclui uma visualização similar das dependências entre pacotes, como ilustrada na Figura 8:
Figura 8. Visualizações do X-Ray das dependências dos pacotes

Estrutura geral
Outro recurso do X-Ray, também baseado no CodeCrawler, apresenta uma
visualização útil do
código. A visualização da complexidade do sistema retrata a sua base de
códigos como um gráfico no qual a hierarquia de descendentes aparece
como uma visualização em árvore descendente, o tamanho da caixa reflete o
número de linhas do código na classe e a largura da caixa, o número de
métodos. A Figura 9 ilustra a visualização da complexidade do sistema:
Figura 9. Visualização da complexidade do sistema X-Ray

A visualização representa ainda as chamadas de saída (acoplamento
eferente) como linhas rosas e as chamadas de entrada (acoplamento
aferente) como linhas vermelhas. Como nas visualizações anteriores,
clicar em uma das caixas abrirá a classe no Eclipse.
Esse nível de
informações fornece uma perspectiva única, difícil de se obter
simplesmente olhando para o código. A localização de deficiências de
projetos em aspectos específicos fica mais fácil quando é possível
filtrar rapidamente determinada dimensões e estreitar as partes do
código que necessitam de investigação adicional.
Resumo
O X-Ray e o iPlasma representam apenas um conjunto pequeno dos tipos de
visualizações disponíveis para o código Java. O uso criterioso deles
estreita rapidamente seu foco para aspectos do projeto que jazem ocultos
nos porões do código.
A localização de padrões idiomáticos é um dos
capacitadores-chave do design emergente, e as ferramentas que facilitam a
identificação de padrões (bons e maus) reduzem grandemente os esforços
investigativos, o que libera mais tempo para refatorar o código e
torná-lo melhor.
Recursos
Aprender
- The Productive Programmer (Neal Ford, O’Reilly Media, 2008): Esse livro detalha diversos tópicos desta série.
- Conjunto de métricas orientadas a objetos de Chidamber e Kemerer: Saiba mais sobre o conjunto de métricas utilizado na ferramenta ckjm.
- CodeCrawler:
Este projeto, que fornece visualizações de métricas para o Smalltalk, é
implementado para as métricas Java pela ferramenta X-Ray. - Moose: O Moose, um ambiente de métricas e visualizações do Smalltalk, é a base do CodeCrawler.
-
Object-Oriented Metrics in Practice
(Michele Lanza and Radu Marinescu, Springer, 2006): Explore as métricas
orientadas a objetos neste livro de coautoria do criador do CodeCrawler
(Lanza). - Vuze: A base de códigos do Vuze BitTorrent Client é usada em um exemplo neste artigo.
-
Navegue até a
livraria de tecnologia para ver livros sobre estes e outros tópicos técnicos. - developerWorks Java technology zone: Encontre centenas de artigos sobre cada aspecto da programação Java.
Obter produtos e tecnologias
- JavaNCSS: Este utilitário de linha de comando mede as métricas do código de origem para a linguagem Java.
- ckjm:
Esta ferramenta de código livre gera os resultados do conjunto de
métricas orientadas a objeto de Chidamber/Kemerer para o código Java. - iPlasma, Uma Plataforma Integrada para Avaliação da Qualidade do Design Orientado a Objetos: Faça Download do iPlasma.
- X-Ray: Faça download de uma versão Java de código livre do CodeCrawler.
artigo publicado originalmente no developerWorks Brasil, por Neal Ford
Neal Ford é um arquiteto de software e Meme Wrangler, na ThoughtWorks,
uma consultoria global de TI. Projeta e desenvolve aplicativos,
materiais de instrução, artigos para revistas, treinamentos e
apresentações em vídeo/DVD, e é autor ou editor de livros que abordam
uma variedade de tecnologias, inclusive The Productive Programmer
Seu enfoque é o projeto e construção de aplicativos corporativos de
grande porte. Também é orador internacionalmente aclamado nas
conferências de desenvolvedores ao redor do mundo. Conheça seu Web site.







