O que significa a 'complexidade ciclomática' do meu código?


42

Eu sou novo na análise estática de código. Meu aplicativo tem uma complexidade ciclomática de 17.754. O aplicativo em si tem apenas 37.672 linhas de código. É válido dizer que a complexidade é alta com base nas linhas de código? O que exatamente a complexidade ciclomática está me dizendo?


Isso depende inteiramente do que você está fazendo. Se você está tentando fazer algo simples, é muito, muito alto. Você não deve ter essa proporção no "olá mundo", por exemplo.
precisa saber é o seguinte

Respostas:


48

O que exatamente a complexidade ciclomática está me dizendo?

A complexidade ciclomática não é uma medida de linhas de código, mas o número de caminhos independentes através de um módulo. Sua complexidade ciclomática de 17.754 significa que seu aplicativo possui 17.754 caminhos exclusivos. Isso tem algumas implicações, geralmente em termos de quão difícil é entender e testar seu aplicativo. Por exemplo, a complexidade ciclomática é o número de casos de teste necessários para atingir 100% de cobertura da filial, assumindo testes bem escritos.

Um bom ponto de partida pode ser o artigo da Wikipedia sobre complexidade ciclomática . Ele tem alguns trechos de pseudocódigo e alguns gráficos que mostram o que é a complexidade ciclomática. Se você quiser saber mais, também pode ler o artigo de McCabe, onde ele definiu a complexidade ciclomática .

Meu aplicativo tem uma complexidade ciclomática de 17.754 linhas de código. O aplicativo em si tem apenas 37.672 linhas de código. É válido dizer que a complexidade é alta com base nas linhas de código?

De modo nenhum. Um aplicativo com poucas linhas de código e um alto número de condicionais aninhados em loops pode ter uma complexidade ciclomática extremamente alta. Por outro lado, um aplicativo com poucas condições pode ter uma baixa complexidade ciclomática. Isso é simplificar demais, mas acho que isso passa a ideia adiante.

Sem saber mais sobre o que seu aplicativo faz, pode ser normal ter uma complexidade ciclomática mais alta. Eu sugeriria medir a complexidade ciclomática em um nível de classe ou método, em vez de apenas um nível de aplicativo. Isso é um pouco mais gerenciável, conceitualmente, eu acho - é mais fácil visualizar ou conceitualizar os caminhos através de um método do que os caminhos através de um aplicativo grande.


36

A complexidade ciclomática é uma maneira de determinar se seu código precisa ser refatorado. O código é analisado e um número de complexidade é determinado. A complexidade é determinada pela ramificação (instruções if, etc.). A complexidade também pode levar em consideração o aninhamento de loops, etc. e outros fatores, dependendo do algoritmo usado.

O número é útil no nível do método. Em níveis mais altos, é apenas um número.

Um número de 17.754 indica a complexidade no nível do projeto (código total), que não tem muito significado.

A análise detalhada da complexidade no nível de classe e método determinará áreas do código que precisam ser refatoradas em métodos menores ou redesenhadas para eliminar a complexidade.

Considere uma CASEdeclaração com 50 casos em um método. Talvez cada estado tenha uma lógica de negócios diferente. Isso gerará uma complexidade ciclomática de 50. Existem 50 pontos de decisão. A instrução CASE pode precisar ser redesenhada usando um padrão de fábrica para se livrar da lógica de ramificação. Às vezes, você pode refatorar (dividir o método em partes menores) e, em alguns casos, apenas um redesenho reduzirá a complexidade.

Em geral, para a complexidade no nível do método:

  • <10 Fácil de manter
  • 11-20 Mais difícil de manter
  • 21+ Candidatos a refatoração / reprojeto

Considere também que complexidades mais altas tornam o código mais difícil de testar na unidade.

A maior complexidade que vi em um único método foi 560. Foram cerca de 2000 linhas de instruções if em um método. Basicamente insustentável, não testável, cheio de possíveis erros. Imagine todos os casos de teste de unidade necessários para essa lógica de ramificação! Não é bom.

Tente manter todos os métodos abaixo de 20 e perceba que há um custo para refatorar qualquer método para torná-lo menos complexo.


Esta é uma resposta melhor.
Pacerier

2
@Pacerier Nesse caso, simplesmente vote a resposta;).
Zero3

> "Em geral, para complexidade no nível do método" Citação?
Benny Bottema

Uma das aplicações originais de McCabe era limitar a complexidade das rotinas durante o desenvolvimento do programa; ele recomendou que os programadores devem contar a complexidade dos módulos que estão em desenvolvimento, e dividi-los em módulos menores sempre que a complexidade ciclomática do módulo excedeu 10.
Jon Raynor

"A declaração CASE pode ter que ser reprojetada usando um padrão de fábrica para se livrar da lógica de ramificação". Por quê? Isso não elimina a complexidade da lógica; apenas o oculta e torna menos aparente e, portanto, mais difícil de manter.
Mason Wheeler

1

É o número de caminhos distintos no seu aplicativo. Confira este artigo da IBM no CC .

Parece alto, mas no seu caso, é a adição do CC de todos os seus métodos, de todas as suas classes e métodos. Meus exemplos são muito extensos, pois não sei como o seu código está estruturado, mas você também pode ter um método monstro com 37672 linhas de código ou 3767 métodos com cerca de 10 linhas de código. O que quero dizer é que, no nível do aplicativo, esse indicador não significa muito, mas no nível do método, ele pode ajudá-lo a otimizar / reescrever seu código em métodos menores, para que sejam menos propensos a erros.

O que eu li pessoalmente muitas vezes é que métodos com um CC maior que 10 têm maiores riscos de defeitos.

Eu uso o Sonar para testar a qualidade do código dos meus aplicativos e, por padrão, acho que gera um aviso se você tiver métodos com +10 CC. Ainda isso pode significar nada. Um exemplo concreto: se você usar o Eclipse para gerar um equalsmétodo baseado nas propriedades do seu bean, o CC irá rapidamente ultrapassar o teto ...


1
A configuração padrão do PMD é alertar para uma complexidade ciclomática de 10 também. Observar a complexidade em um nível por método também permite desconsiderar métodos que possam ter boas razões para um alto CC, como equalsmétodos gerados .
Thomas Owens

Eu não tinha certeza, então verifiquei, mas o Sonar usa internamente o PMD para obter essa medida. Então, tudo faz sentido :-)
Jalayn

-1

Depende de qual ferramenta você usou. Algumas das ferramentas de código-fonte aberto existentes classificam como módulo ou outro nível de estrutura como módulo. Portanto, quanto maior o projeto, maior a complexidade ciclomática que ele tende a obter. No entanto, para meu entendimento pessoal, ele deve ser baseado em funções. Como o projeto é maior, as funções que ele desempenha.

Eu recomendo que você use a ferramenta chamada Lizard e encontre o código do recurso e faça o download do arquivo zip no github. Ele também possui uma versão online, se não houver muitas informações confidenciais no seu código.

O CCN significativo com o qual você deve se preocupar está em uma base de funções diferente de qualquer outra. Além disso, manter o CCN de cada função unber 15 seria a faixa ideal.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.