SlideShare uma empresa Scribd logo
1 de 46
Baixar para ler offline
Complexidade Ciclomática ou Cognitiva?
Eis a questão
DOUGLAS SIVIOTTI
TDC Connections, BH, 22 de Março de 2023
Free images by:
Sobre
DOUGLAS SIVIOTTI
Analista de sistemas com especialização em
engenharia de software pela Universidade Federal
do Rio Grande do Sul; e especialização em Proteção
e Uso de Dados pela PUC-MG.
Atua com desenvolvimento há mais de 20 anos e é
arquiteto e software do SERPRO desde 2005. Nos
últimos anos atua especialmente com arquitetura,
qualidade de software, segurança e proteção de
dados (LGPD), sendo um dos criadores do "guia de
desenvolvimento confiável" do SERPRO.
Autor do blog ArteSoftware.com.br
Foco/Objetivos da Palestra:
1. Apresentação das métricas de complexidade
ciclomática e complexidade cognitiva
2. Semelhanças e diferenças entre elas
3. Qual aplicar e quando
Agenda: 46 Slides (~30min) em 4 partes:
1. Introdução e Exemplos
2. Complexidade Ciclomática
3. Complexidade Cognitiva
4. Similaridades e Diferenças
Complexidade?
1
2
Complexidade?
1
2
Cognitiva
Ciclomática
0
1
Cognitiva
Ciclomática
5
3
Nada Complexo
Alguma Complexidade
É a métrica de software que indica a
complexidade de um programa* (McCabe, 1976)
* Programa, método, função etc
Ela mede a quantidade máxima de
caminhos linearmente independentes
Complexidade
Ciclomática
É a métrica de software que mede a
quantidade de quebras do fluxo linear
de leitura ponderadas por nível de
aninhamento dessas quebras. Mede o
quão difícil é entender um código.
Complexidade
Cognitiva
Exemplo 1
Cognitiva
Ciclomática
6
4
+1...
+1
public int precoSorvete(boolean premium, boolean casquinha, int coberturas) {
int preco = 0;
if (premium) {
preco = 20;
} else {
preco = 15;
}
if (casquinha) {
preco = preco + 2;
} else {
preco = preco + 1;
}
if (coberturas > 1){
preco = preco + 2;
} else {
preco = preco + 1;
}
return preco;
}
if
15 20
if
+1 +2
if
+1 +2
P
0
+1
+1
+1
+1
+1
+1
+1
Exemplo 2
IF
+5
+1
+1
IF
+1
P
15
+1
IF
public int precoSorvete(boolean premium,boolean casquinha, int coberturas){
int preco = 15;
if (premium) {
preco = preco + 5;
}
preco = preco + 1;
if (casquinha) {
preco = preco + 1;
}
preco = preco + 1;
if (coberturas > 1){
preco = preco + 1;
}
return preco;
}
Cognitiva
Ciclomática
3
4
+1...
+1
+1
+1
+1
+1
Exemplo 3
IF
17 20
IF
+1
+2
IF
+1 +2
P
0
public int precoSorvete(boolean premium, boolean casquinha, int coberturas) {
int preco = 0;
if (premium) {
preco = 20;
if (casquinha) {
preco = preco + 2;
if (coberturas > 1){
preco = preco + 2;
} else {
preco = preco + 1;
}
} else {
preco = preco + 1;
}
} else {
preco = 15 + 1 + 1;
}
return preco;
}
Cognitiva
Ciclomática
9
4
+1
+1
+1...
+1
+2
+3
+1
+1
+1
É a métrica de software que indica a
complexidade de um programa* (McCabe, 1976)
* Programa, método, função etc
Ela mede a quantidade máxima de
caminhos linearmente independentes
Complexidade
Ciclomática
Modo Complexo de Calcular Complexidade Ciclomática (Esqueça!)
Nó
Aresta
CC = Arestas – Nós + 1 if
17 20
if
+1
+2
If
+1 +2
P
0
CC = 14 – 11 + 1 = 4
Preciso desenhar um
grafo para cada método
para calcular?
Preciso desenhar um
grafo para cada método
para calcular?
Modo Simplificado de Cálculo Por Palavras Reservadas de Desvio de Fluxo
1. Inicia em “Um” para o método (com ou sem retorno)
2. Adiciona “Um” para cada elemento de fluxo abaixo:
2.1 Seleção if, case
2.2 Loops for, while, do-while, break, e
continue.
2.3 Operadores &&, ||, ?
2.4 Exceções catch, finally, throw, ou throws
2.5 Fluxo return que não seja o último
(else, default, finally, : e return não incrementam o valor)
Melhor Modo de Calcular: Não Calcular, Usar Ferramenta de SAST
Exemplo 2
IF
+5
+1
+1
IF
+1
P
15
+1
IF
public int precoSorvete(boolean premium,boolean casquinha, int coberturas){
int preco = 15;
if (premium) {
preco = preco + 5;
}
preco = preco + 1;
if (casquinha) {
preco = preco + 1;
}
preco = preco + 1;
if (coberturas > 1){
preco = preco + 1;
}
return preco;
}
Ciclomática 4
+1
+1
CC = 4, logo são 4
caminhos possíveis?
CC = 4, logo são 4
caminhos possíveis?
Caminhos Possíveis do Exemplo 2
if
+5
+1
+1
if
+1
18
15
+1
if
if
+5
+1
+1
if
+1
17
15
+1
if
if
+5
+1
+1
if
+1
18
15
+1
if
if
+5
+1
+1
if
+1
19
15
+1
if
if
+5
+1
+1
if
+1
23
15
+1
if
if
+5
+1
+1
if
+1
22
15
+1
if
if
+5
+1
+1
if
+1
23
15
+1
if
if
+5
+1
+1
if
+1
24
15
+1
if
Com
Copo
1 Cob
Prem
Copo
1 Cob
Com
Copo
2 Cob
Com
Casc
1 Cob
Com
Casc
2 Cob
Prem
Copo
2 Cob
Prem
CAsc
2 Cob
Prem
Casc
2 Cob
Caminhos Possíveis do Exemplo 1
if
15 20
if
+1 +2
if
+1 +2
17
0
if
15 20
if
+1 +2
if
+1 +2
18
0
if
15 20
if
+1 +2
if
+1 +2
18
0
if
15 20
if
+1 +2
if
+1 +2
19
0
if
15 20
if
+1 +2
if
+1 +2
22
0
if
15 20
if
+1 +2
if
+1 +2
23
0
if
15 20
if
+1 +2
if
+1 +2
23
0
if
15 20
if
+1 +2
if
+1 +2
24
0
Premium
Copinho
1 Cobertura
Comum
Copinho
1 Cobertura
Comum
Copinho
2 Coberturas
Comum
Casquinha
1 Cobertura
Comum
Casquinha
2 Coberturas
Premium
Copinho
2 Coberturas
Premium
Casquinha
1 Cobertura
Premium
Casquinha
2 Coberturas
Cenários para 100% dos Caminhos (NPATH) e 100% das Linhas (Coverage)
assertEquals(17, sorveteria.precoSorvete(false, false, 1)); // Comum-Copinho-1Cob
assertEquals(18, sorveteria.precoSorvete(false, false, 2)); // Comum-Copinho-2Cob
assertEquals(18, sorveteria.precoSorvete(false, true, 1)); // Comum-Casquinha-1Cob
assertEquals(19, sorveteria.precoSorvete(false, true, 2)); // Comum-Casquinha-2Cob
assertEquals(22, sorveteria.precoSorvete(true, false, 1)); // Premium-Copinho-1Cob
assertEquals(23, sorveteria.precoSorvete(true, false, 2)); // Premium-Copinho-2Cob
assertEquals(23, sorveteria.precoSorvete(true, true, 1)); // Premium-Casquinha-1Cob
assertEquals(24, sorveteria.precoSorvete(true, true, 2)); // Premium-Casquinha-2Cob
Mais um IF e são 16 caminhos, 10 IFs são 1024 Caminhos! Impossível Testar.
Caminho Linearmente Independente
Caminho Linearmente Independente é qualquer caminho do
programa que introduz pelo menos um novo conjunto de
comandos de processamento ou uma nova condição. Quando
definido em termos de grafo de fluxo, um caminho
independente deve incluir pelo menos uma aresta que não
tenha sido atravessada antes de o caminho ser definido
(Pressman).
1
B X
2
C Y
A
Independentes: A-1-B-2-C-D A-1-X-2-C-D A-1-B-2-Y-D
Não Independente: A-1-X-2-Y-D
D
Caminho Linearmente Independente
1
B X
2
C Y
A
Independentes: A-1-B-2-C-D A-1-X-2-C-D A-1-B-2-Y-D
Não Independente: A-1-X-2-Y-D
D
1
B X
2
C Y
A
D
1
B X
2
C Y
A
D
1
B X
2
C Y
A
D
A B C D
4 Caminhos Linearmente Independentes: Comlexidade Ciclomática = 4
B
if
+5
+1
+1
if
+1
P
15
+1
if
A
if
+5
+1
+1
if
+1
P
15
+1
if
C
if
+5
+1
+1
if
+1
P
15
+1
if
D
if
+5
+1
+1
if
+1
P
15
+1
if
4 Caminhos linearmente independentes
Exemplo 1: São Necessários Dois Cenários Para Cobrir 100% das Linhas
assertEquals(17,
sorveteria.precoSorvete
(false, false, 1));
assertEquals(24,
sorveteria.precoSorvete
(true, true, 2));
if
15 20
if
+1 +2
if
+1 +2
17
0
if
15 20
if
+1 +2
if
+1 +2
22
0
A B
Exemplo 2: Apenas 1 Cenário Cobre 100% das Linhas
assertEquals(24,
sorveteria.precoSorvete
(true, true, 2));
if
+5
+1
+1
if
+1
P
15
+1
if
IF
17 20
IF
+1
+2
IF
+1 +2
P
0
public int precoSorvete(boolean premium, boolean casquinha, int coberturas) {
int preco = 0;
if (premium) {
preco = 20;
if (casquinha) {
preco = preco + 2;
if (coberturas > 1){
preco = preco + 2;
} else {
preco = preco + 1;
}
} else {
preco = preco + 1;
}
} else {
preco = 15 + 1 + 1;
}
return preco;
}
Ciclomática 4
+1
+1
Exemplo 3: Quantos Cenários São Necessários Para Cobrir 100% das Linhas?
Exemplo 3: Quantos Cenários São Necessários Para Cobrir 100% das Linhas?
if
17 20
if
+1
+2
If
+1 +2
P
0
A
if
17 20
if
+1
+2
If
+1 +2
P
0
B
if
17 20
if
+1
+2
If
+1 +2
P
0
D C
Exemplo 3: São Necessários 4 Cenários Para Cobrir 100% das Linhas
17 = (false, false, 1) // 1
24 = (true, true, 2)) // 2
23 = (true, true, 1)) // 3
21 = (true, false, 2)) // 4
if
17 20
if
+1
+2
If
+1 +2
0
A
if
17 20
if
21
+2
If
23 24
0
C
D
B
Utilidade da Complexidade Ciclomática: Testabilidade
Dependendo do algoritmo, a quantidade de caminhos
únicos pode variar, mas o valor de complexidade
ciclomática é o limite superior do número de
cenários necessários para cobrir 100% das linhas e
condições, se definidos corretamente
É a métrica de software que mede a
quantidade de quebras do fluxo linear
de leitura ponderadas por nível de
aninhamento dessas quebras. Mede o
quão difícil é entender um código.
Complexidade
Cognitiva
if
15 20
if
+1 +2
if
+1 +2
P
0
if
+5
+1
+1
if
+1
P
15
+1
if
1 2
if
17 20
if
+1
+2
If
+1 +2
P
0
3
Cognitiva
Ciclomática
6
4
Cognitiva
Ciclomática
3
4
Cognitiva
Ciclomática
9
4
Baixa “Sensibilidade” da Complexidade Ciclomática
Método para cálculo da soma de todos os
números primos até um máximo informado
Método que retorna um texto relativo ao
parâmetro passado através de um “switch”
https://www.sonarsource.com/docs/CognitiveComplexity.pdf
Ciclomática
Cognitiva
4
7
Ciclomática
Cognitiva
4
1
Filosofia
●
Foco no problema do programador (dificuldade de entendimento, não caminhos)
●
Quebras no fluxo linear aumentam o esforço de entendimento
●
Aninhamentos aumentam ainda mais o esforço gerado por uma quebra
●
Incentivo a boas práticas, beneficiando as boas escolhas (e.g. “?.”, cláusula de guarda)
●
Os testes passam
●
Revela intenção
●
Nenhuma duplicação
●
Mínimo de elementos
https://martinfowler.com/bliki/BeckDesignRules.html
Clean Code
Regras de Contagem
Regra 1: Ignorar Abreviações
Ignorar estruturas em que várias instruções podem ser abreviadas para apenas uma (incentiva boas práticas)
Regra 2: Incrementar por Quebra de Fluxo (similar a Complexidade Ciclomática)
Incrementar um ponto a cada quebra no fluxo linear do código
+ 1 ponto para: if, else if, else, operador ternário, switch, for, foreach, while, do while,
catch, goto LABEL, break LABEL, continue LABEL, sequência de operadores lógicos (&&, || etc) e
cada recurção encontrada
Regra 3: Incrementar por Aninhamento
Incrementar um ponto a cada nível de aninhamento de uma quebra de fluxo (além do ponto por quebra - R2)
+ 1 nível para: if, else if, else, operador ternário, switch, foreach, while, do while catch,
métodos aninhados e métodos ou estruturas tipo lambda
+ 1 ponto para: if, operador ternário, switch, for, foreach, while, do while e catch.
Exemplo da Regra 1
Ignorar estruturas em que várias instruções podem ser abreviadas para apenas uma
Refatoração
Cognitiva 0
Cognitiva 1
O cálculo privilegia boas práticas. O código à direita é mais fácil de entender
“Safe Navigation Operator”
Exemplo da Regra 2 e 3
IF
17 20
IF
+1
+2
IF
+1 +2
P
0
public int precoSorvete(boolean premium, boolean casquinha, int coberturas) {
int preco = 0;
if (premium) {
preco = 20;
if (casquinha) {
preco = preco + 2;
if (coberturas > 1){
preco = preco + 2;
} else {
preco = preco + 1;
}
} else {
preco = preco + 1;
}
} else {
preco = 15 + 1 + 1;
}
return preco;
}
Cognitiva 9
+1
+1
+1...
+1
+2
+3
+1
Particularidades da Regra 2: Sequências && e ||
Sequências de operadores iguais geram incremento de um ponto
Operadores alternados contam um ponto cada um
“a && b” = “a && b && c && d” “a || b” = “a || b || c || d”
Uma sequência de “E” é lida como
“todos esses”
Uma sequência de “OU” é lida como
“algum desses”
Particularidades da Regra 2: Catch e Switch
Catch gera o incremento de um ponto
●
Um “catch” representa um desvio no fluxo da mesma forma que um “if”
●
Incrementa um ponto independentemente de quantas exceções são tratadas
catch (NullPointerException | IoException | IllegalArgumentException e)
Switch gera o incremento de um ponto
●
Apenas a variável de decisão precisa ser compreendida
●
A quantidade de “cases” não aumenta a dificuldade
de entendimento (é lido como “um desses”)
●
Na C. Ciclomática cada “case” aumenta em um ponto!
Momento Clean Code: O Que Está Ruim Abaixo?
public int precoSorvete(boolean premium, boolean casquinha, int coberturas) {
if (coberturas <= 3) {
int preco = 0;
if (premium) {
preco = 20;
if (casquinha) {
preco = preco + 2;
if (coberturas > 1){
preco = preco + 2;
} else {
preco = preco + 1;
}
} else {
preco = preco + 1;
}
} else {
preco = 15 + 1 + 1;
}
return preco;
}
return 0;
}
Muita Coisa Está Ruim! Inclusive Complexidade
public int precoSorvete(boolean premium, boolean casquinha, int coberturas) {
if (coberturas <= 3) {
int preco = 0;
if (premium) {
preco = 20;
if (casquinha) {
preco = preco + 2;
if (coberturas > 1){
preco = preco + 2;
} else {
preco = preco + 1;
}
} else {
preco = preco + 1;
}
} else {
preco = 15 + 1 + 1;
}
return preco;
}
return 0;
}
+1
+2
+3
+4
Cognitiva 13
+1
+1
+1
Problemas:
●
Retorno sem semântica (Zero ou null)
●
Mais difícil de ler (+ 1 IF)
●
Pré condição misturada com código de
negócio. Mais difícil testar e refatorar
Cláusula de Guarda (Incentivo a Boas Práticas)
public int precoSorvete(boolean premium, boolean casquinha, int coberturas) {
if (coberturas > 3) {
throw new IllegalArgumentException(“O máximo de coberturas é 3!);
}
int preco = 0;
if (premium) {
preco = 20;
if (casquinha) {
preco = preco + 2;
if (coberturas > 1){
preco = preco + 2;
} else {
preco = preco + 1;
}
} else {
preco = preco + 1;
}
} else {
preco = 15 + 1 + 1;
}
return preco;
}
Cláusula de Guarda
Cognitiva 10
Melhorias:
●
Retorno somente com semântica
●
Mais simples de entender
●
Pré condição separada do negócio
●
Exceção clara sobre mau uso do método
Cláusula de Guarda (Incentivo a Boas Práticas)
Cognitiva
Ciclomática
6
4
+1
+2
+3
Cláusula de Guarda (Incentivo a Boas Práticas)
Cognitiva
Ciclomática
3
4
+1
+1
+1
Utilidade da Complexidade Cognitiva: Legibilidade
1. Score mais acurado para legibilidade
2. Contempla estruturas modernas (operador ?, lambdas)
3. Mede níveis acima de método (classe, pacote, sistema etc)
Complexidade Ciclomática: Testabilidade
Complexidade Cognitiva: Legibilidade
Similaridades
e Diferenças
Resumo das Similaridades
1. Ambas se propõe a medir complexidade de um método ou função
2. Ambas incrementam a contagem por quebra de fluxo pontuando
palavras reservadas (IF, For, While etc)
3. Ambas são suportadas por ferramentas de SAST
4. Ambas devem ser mantidas com valores baixos (menor = melhor)
Resumo das Diferenças
1. C. Cognitiva mede além de métodos: classe, pacote e sistema
2. C. Ciclomática sempre incrementa “+1”; C. Cognitiva pontua extra
por nível de aninhamento, mas só 1 p/ sequências (E, OU, Catch, Switch)
3. C. Cognitiva é nativa do Sonar, C. Ciclomática é padrão de mercado
4. Refatoração para melhorar complexidade de leitura é o melhor
começo para sair da inércia da divida técnica. (mais fácil que teste de unid.)
Complexidade Ciclomática ou Cognitiva?
Eis a Questão...
Complexidade Cognitiva
Complexidade Ciclomática
Perguntas...
Contatos
DOUGLAS SIVIOTTI
/douglas-siviotti
douglas.siviotti@gmail.com
facebook.com/
artesoftware.com.br
artesoftware.com.br
instagram.com/
artesoftware

Mais conteúdo relacionado

Semelhante a Complexidade Ciclomática vs Cognitiva

Semana 1: Programação como arte de resolver problemas, algoritmos e problema...
Semana  1: Programação como arte de resolver problemas, algoritmos e problema...Semana  1: Programação como arte de resolver problemas, algoritmos e problema...
Semana 1: Programação como arte de resolver problemas, algoritmos e problema...Manuel Menezes de Sequeira
 
Programação Estruturada 2 - Curso Completo
Programação Estruturada 2 - Curso CompletoProgramação Estruturada 2 - Curso Completo
Programação Estruturada 2 - Curso Completothomasdacosta
 
Introdução Programação Em Maple
Introdução Programação Em MapleIntrodução Programação Em Maple
Introdução Programação Em Maplejeandson correa
 
5 expressoes logicas - operadores - base binaria - operadores de bits
5   expressoes logicas - operadores - base binaria - operadores de bits5   expressoes logicas - operadores - base binaria - operadores de bits
5 expressoes logicas - operadores - base binaria - operadores de bitsRicardo Bolanho
 
TDC2016SP - SparkMLlib Machine Learning na Prática
TDC2016SP -  SparkMLlib Machine Learning na PráticaTDC2016SP -  SparkMLlib Machine Learning na Prática
TDC2016SP - SparkMLlib Machine Learning na Práticatdc-globalcode
 

Semelhante a Complexidade Ciclomática vs Cognitiva (11)

Semana 1: Programação como arte de resolver problemas, algoritmos e problema...
Semana  1: Programação como arte de resolver problemas, algoritmos e problema...Semana  1: Programação como arte de resolver problemas, algoritmos e problema...
Semana 1: Programação como arte de resolver problemas, algoritmos e problema...
 
Curso de Simulink
Curso de SimulinkCurso de Simulink
Curso de Simulink
 
Programação Estruturada 2 - Curso Completo
Programação Estruturada 2 - Curso CompletoProgramação Estruturada 2 - Curso Completo
Programação Estruturada 2 - Curso Completo
 
Introdução Programação Em Maple
Introdução Programação Em MapleIntrodução Programação Em Maple
Introdução Programação Em Maple
 
0001
00010001
0001
 
000003 complexidade
000003 complexidade000003 complexidade
000003 complexidade
 
5 expressoes logicas - operadores - base binaria - operadores de bits
5   expressoes logicas - operadores - base binaria - operadores de bits5   expressoes logicas - operadores - base binaria - operadores de bits
5 expressoes logicas - operadores - base binaria - operadores de bits
 
decisão aninhada programaçao de cmputadores
decisão aninhada programaçao de cmputadoresdecisão aninhada programaçao de cmputadores
decisão aninhada programaçao de cmputadores
 
Aula1.pdf
Aula1.pdfAula1.pdf
Aula1.pdf
 
TDC2016SP - SparkMLlib Machine Learning na Prática
TDC2016SP -  SparkMLlib Machine Learning na PráticaTDC2016SP -  SparkMLlib Machine Learning na Prática
TDC2016SP - SparkMLlib Machine Learning na Prática
 
Aula 4 poe
Aula 4 poeAula 4 poe
Aula 4 poe
 

Mais de Douglas Siviotti

tdc-2022-poa-quem-tem-medo-low-code.pdf
tdc-2022-poa-quem-tem-medo-low-code.pdftdc-2022-poa-quem-tem-medo-low-code.pdf
tdc-2022-poa-quem-tem-medo-low-code.pdfDouglas Siviotti
 
tdc-2022-poa-lgpd-metaverso.pdf
tdc-2022-poa-lgpd-metaverso.pdftdc-2022-poa-lgpd-metaverso.pdf
tdc-2022-poa-lgpd-metaverso.pdfDouglas Siviotti
 
TDC Future 2021 - Privacy After Design
TDC Future 2021 - Privacy After DesignTDC Future 2021 - Privacy After Design
TDC Future 2021 - Privacy After DesignDouglas Siviotti
 
TDC Connections 2021 Artigo 37 da LGPD
TDC Connections 2021 Artigo 37 da LGPDTDC Connections 2021 Artigo 37 da LGPD
TDC Connections 2021 Artigo 37 da LGPDDouglas Siviotti
 
Como o SERPRO Atende os Direitos dos Titulares
Como o SERPRO Atende os Direitos dos TitularesComo o SERPRO Atende os Direitos dos Titulares
Como o SERPRO Atende os Direitos dos TitularesDouglas Siviotti
 
Tdc 2021-innovation-lgpd-dados-pessoais
Tdc 2021-innovation-lgpd-dados-pessoaisTdc 2021-innovation-lgpd-dados-pessoais
Tdc 2021-innovation-lgpd-dados-pessoaisDouglas Siviotti
 
Artesoftware Explicando LGPD
Artesoftware Explicando LGPDArtesoftware Explicando LGPD
Artesoftware Explicando LGPDDouglas Siviotti
 
tdc-2020-poa-pedra-tesoura-papel
tdc-2020-poa-pedra-tesoura-papeltdc-2020-poa-pedra-tesoura-papel
tdc-2020-poa-pedra-tesoura-papelDouglas Siviotti
 
Tdc 2020-poa-data-protection-full-stack
Tdc 2020-poa-data-protection-full-stackTdc 2020-poa-data-protection-full-stack
Tdc 2020-poa-data-protection-full-stackDouglas Siviotti
 
tdc-recife-2020-lgpd-para-desenvolvedores
tdc-recife-2020-lgpd-para-desenvolvedorestdc-recife-2020-lgpd-para-desenvolvedores
tdc-recife-2020-lgpd-para-desenvolvedoresDouglas Siviotti
 
Privacidade By Design no Ciclo de Vida do Produto
Privacidade By Design no Ciclo de Vida do ProdutoPrivacidade By Design no Ciclo de Vida do Produto
Privacidade By Design no Ciclo de Vida do ProdutoDouglas Siviotti
 
LGPD Lei Geral de Proteção de Dados Pessoais
LGPD Lei Geral de Proteção de Dados PessoaisLGPD Lei Geral de Proteção de Dados Pessoais
LGPD Lei Geral de Proteção de Dados PessoaisDouglas Siviotti
 
Negócio Escrito em Código
Negócio Escrito em CódigoNegócio Escrito em Código
Negócio Escrito em CódigoDouglas Siviotti
 

Mais de Douglas Siviotti (17)

tdc-2022-poa-quem-tem-medo-low-code.pdf
tdc-2022-poa-quem-tem-medo-low-code.pdftdc-2022-poa-quem-tem-medo-low-code.pdf
tdc-2022-poa-quem-tem-medo-low-code.pdf
 
tdc-2022-poa-lgpd-metaverso.pdf
tdc-2022-poa-lgpd-metaverso.pdftdc-2022-poa-lgpd-metaverso.pdf
tdc-2022-poa-lgpd-metaverso.pdf
 
TDC Future 2021 - Privacy After Design
TDC Future 2021 - Privacy After DesignTDC Future 2021 - Privacy After Design
TDC Future 2021 - Privacy After Design
 
TDC Connections 2021 Artigo 37 da LGPD
TDC Connections 2021 Artigo 37 da LGPDTDC Connections 2021 Artigo 37 da LGPD
TDC Connections 2021 Artigo 37 da LGPD
 
Como o SERPRO Atende os Direitos dos Titulares
Como o SERPRO Atende os Direitos dos TitularesComo o SERPRO Atende os Direitos dos Titulares
Como o SERPRO Atende os Direitos dos Titulares
 
Tdc 2021-innovation-lgpd-dados-pessoais
Tdc 2021-innovation-lgpd-dados-pessoaisTdc 2021-innovation-lgpd-dados-pessoais
Tdc 2021-innovation-lgpd-dados-pessoais
 
Artesoftware Explicando LGPD
Artesoftware Explicando LGPDArtesoftware Explicando LGPD
Artesoftware Explicando LGPD
 
tdc-2020-poa-pedra-tesoura-papel
tdc-2020-poa-pedra-tesoura-papeltdc-2020-poa-pedra-tesoura-papel
tdc-2020-poa-pedra-tesoura-papel
 
Tdc 2020-poa-data-protection-full-stack
Tdc 2020-poa-data-protection-full-stackTdc 2020-poa-data-protection-full-stack
Tdc 2020-poa-data-protection-full-stack
 
tdc-recife-2020-lgpd-para-desenvolvedores
tdc-recife-2020-lgpd-para-desenvolvedorestdc-recife-2020-lgpd-para-desenvolvedores
tdc-recife-2020-lgpd-para-desenvolvedores
 
Privacidade By Design no Ciclo de Vida do Produto
Privacidade By Design no Ciclo de Vida do ProdutoPrivacidade By Design no Ciclo de Vida do Produto
Privacidade By Design no Ciclo de Vida do Produto
 
clean code
clean codeclean code
clean code
 
Privacidade By Design
Privacidade By DesignPrivacidade By Design
Privacidade By Design
 
LGPD Lei Geral de Proteção de Dados Pessoais
LGPD Lei Geral de Proteção de Dados PessoaisLGPD Lei Geral de Proteção de Dados Pessoais
LGPD Lei Geral de Proteção de Dados Pessoais
 
Clean Code na Prática
Clean Code na PráticaClean Code na Prática
Clean Code na Prática
 
Negócio Escrito em Código
Negócio Escrito em CódigoNegócio Escrito em Código
Negócio Escrito em Código
 
Dívida Técnica
Dívida TécnicaDívida Técnica
Dívida Técnica
 

Complexidade Ciclomática vs Cognitiva

  • 1. Complexidade Ciclomática ou Cognitiva? Eis a questão DOUGLAS SIVIOTTI TDC Connections, BH, 22 de Março de 2023 Free images by:
  • 2. Sobre DOUGLAS SIVIOTTI Analista de sistemas com especialização em engenharia de software pela Universidade Federal do Rio Grande do Sul; e especialização em Proteção e Uso de Dados pela PUC-MG. Atua com desenvolvimento há mais de 20 anos e é arquiteto e software do SERPRO desde 2005. Nos últimos anos atua especialmente com arquitetura, qualidade de software, segurança e proteção de dados (LGPD), sendo um dos criadores do "guia de desenvolvimento confiável" do SERPRO. Autor do blog ArteSoftware.com.br Foco/Objetivos da Palestra: 1. Apresentação das métricas de complexidade ciclomática e complexidade cognitiva 2. Semelhanças e diferenças entre elas 3. Qual aplicar e quando Agenda: 46 Slides (~30min) em 4 partes: 1. Introdução e Exemplos 2. Complexidade Ciclomática 3. Complexidade Cognitiva 4. Similaridades e Diferenças
  • 5. É a métrica de software que indica a complexidade de um programa* (McCabe, 1976) * Programa, método, função etc Ela mede a quantidade máxima de caminhos linearmente independentes Complexidade Ciclomática
  • 6. É a métrica de software que mede a quantidade de quebras do fluxo linear de leitura ponderadas por nível de aninhamento dessas quebras. Mede o quão difícil é entender um código. Complexidade Cognitiva
  • 7. Exemplo 1 Cognitiva Ciclomática 6 4 +1... +1 public int precoSorvete(boolean premium, boolean casquinha, int coberturas) { int preco = 0; if (premium) { preco = 20; } else { preco = 15; } if (casquinha) { preco = preco + 2; } else { preco = preco + 1; } if (coberturas > 1){ preco = preco + 2; } else { preco = preco + 1; } return preco; } if 15 20 if +1 +2 if +1 +2 P 0 +1 +1 +1 +1 +1 +1 +1
  • 8. Exemplo 2 IF +5 +1 +1 IF +1 P 15 +1 IF public int precoSorvete(boolean premium,boolean casquinha, int coberturas){ int preco = 15; if (premium) { preco = preco + 5; } preco = preco + 1; if (casquinha) { preco = preco + 1; } preco = preco + 1; if (coberturas > 1){ preco = preco + 1; } return preco; } Cognitiva Ciclomática 3 4 +1... +1 +1 +1 +1 +1
  • 9. Exemplo 3 IF 17 20 IF +1 +2 IF +1 +2 P 0 public int precoSorvete(boolean premium, boolean casquinha, int coberturas) { int preco = 0; if (premium) { preco = 20; if (casquinha) { preco = preco + 2; if (coberturas > 1){ preco = preco + 2; } else { preco = preco + 1; } } else { preco = preco + 1; } } else { preco = 15 + 1 + 1; } return preco; } Cognitiva Ciclomática 9 4 +1 +1 +1... +1 +2 +3 +1 +1 +1
  • 10. É a métrica de software que indica a complexidade de um programa* (McCabe, 1976) * Programa, método, função etc Ela mede a quantidade máxima de caminhos linearmente independentes Complexidade Ciclomática
  • 11. Modo Complexo de Calcular Complexidade Ciclomática (Esqueça!) Nó Aresta CC = Arestas – Nós + 1 if 17 20 if +1 +2 If +1 +2 P 0 CC = 14 – 11 + 1 = 4 Preciso desenhar um grafo para cada método para calcular? Preciso desenhar um grafo para cada método para calcular?
  • 12. Modo Simplificado de Cálculo Por Palavras Reservadas de Desvio de Fluxo 1. Inicia em “Um” para o método (com ou sem retorno) 2. Adiciona “Um” para cada elemento de fluxo abaixo: 2.1 Seleção if, case 2.2 Loops for, while, do-while, break, e continue. 2.3 Operadores &&, ||, ? 2.4 Exceções catch, finally, throw, ou throws 2.5 Fluxo return que não seja o último (else, default, finally, : e return não incrementam o valor)
  • 13. Melhor Modo de Calcular: Não Calcular, Usar Ferramenta de SAST
  • 14. Exemplo 2 IF +5 +1 +1 IF +1 P 15 +1 IF public int precoSorvete(boolean premium,boolean casquinha, int coberturas){ int preco = 15; if (premium) { preco = preco + 5; } preco = preco + 1; if (casquinha) { preco = preco + 1; } preco = preco + 1; if (coberturas > 1){ preco = preco + 1; } return preco; } Ciclomática 4 +1 +1 CC = 4, logo são 4 caminhos possíveis? CC = 4, logo são 4 caminhos possíveis?
  • 15. Caminhos Possíveis do Exemplo 2 if +5 +1 +1 if +1 18 15 +1 if if +5 +1 +1 if +1 17 15 +1 if if +5 +1 +1 if +1 18 15 +1 if if +5 +1 +1 if +1 19 15 +1 if if +5 +1 +1 if +1 23 15 +1 if if +5 +1 +1 if +1 22 15 +1 if if +5 +1 +1 if +1 23 15 +1 if if +5 +1 +1 if +1 24 15 +1 if Com Copo 1 Cob Prem Copo 1 Cob Com Copo 2 Cob Com Casc 1 Cob Com Casc 2 Cob Prem Copo 2 Cob Prem CAsc 2 Cob Prem Casc 2 Cob
  • 16. Caminhos Possíveis do Exemplo 1 if 15 20 if +1 +2 if +1 +2 17 0 if 15 20 if +1 +2 if +1 +2 18 0 if 15 20 if +1 +2 if +1 +2 18 0 if 15 20 if +1 +2 if +1 +2 19 0 if 15 20 if +1 +2 if +1 +2 22 0 if 15 20 if +1 +2 if +1 +2 23 0 if 15 20 if +1 +2 if +1 +2 23 0 if 15 20 if +1 +2 if +1 +2 24 0 Premium Copinho 1 Cobertura Comum Copinho 1 Cobertura Comum Copinho 2 Coberturas Comum Casquinha 1 Cobertura Comum Casquinha 2 Coberturas Premium Copinho 2 Coberturas Premium Casquinha 1 Cobertura Premium Casquinha 2 Coberturas
  • 17. Cenários para 100% dos Caminhos (NPATH) e 100% das Linhas (Coverage) assertEquals(17, sorveteria.precoSorvete(false, false, 1)); // Comum-Copinho-1Cob assertEquals(18, sorveteria.precoSorvete(false, false, 2)); // Comum-Copinho-2Cob assertEquals(18, sorveteria.precoSorvete(false, true, 1)); // Comum-Casquinha-1Cob assertEquals(19, sorveteria.precoSorvete(false, true, 2)); // Comum-Casquinha-2Cob assertEquals(22, sorveteria.precoSorvete(true, false, 1)); // Premium-Copinho-1Cob assertEquals(23, sorveteria.precoSorvete(true, false, 2)); // Premium-Copinho-2Cob assertEquals(23, sorveteria.precoSorvete(true, true, 1)); // Premium-Casquinha-1Cob assertEquals(24, sorveteria.precoSorvete(true, true, 2)); // Premium-Casquinha-2Cob Mais um IF e são 16 caminhos, 10 IFs são 1024 Caminhos! Impossível Testar.
  • 18. Caminho Linearmente Independente Caminho Linearmente Independente é qualquer caminho do programa que introduz pelo menos um novo conjunto de comandos de processamento ou uma nova condição. Quando definido em termos de grafo de fluxo, um caminho independente deve incluir pelo menos uma aresta que não tenha sido atravessada antes de o caminho ser definido (Pressman). 1 B X 2 C Y A Independentes: A-1-B-2-C-D A-1-X-2-C-D A-1-B-2-Y-D Não Independente: A-1-X-2-Y-D D
  • 19. Caminho Linearmente Independente 1 B X 2 C Y A Independentes: A-1-B-2-C-D A-1-X-2-C-D A-1-B-2-Y-D Não Independente: A-1-X-2-Y-D D 1 B X 2 C Y A D 1 B X 2 C Y A D 1 B X 2 C Y A D A B C D
  • 20. 4 Caminhos Linearmente Independentes: Comlexidade Ciclomática = 4 B if +5 +1 +1 if +1 P 15 +1 if A if +5 +1 +1 if +1 P 15 +1 if C if +5 +1 +1 if +1 P 15 +1 if D if +5 +1 +1 if +1 P 15 +1 if 4 Caminhos linearmente independentes
  • 21. Exemplo 1: São Necessários Dois Cenários Para Cobrir 100% das Linhas assertEquals(17, sorveteria.precoSorvete (false, false, 1)); assertEquals(24, sorveteria.precoSorvete (true, true, 2)); if 15 20 if +1 +2 if +1 +2 17 0 if 15 20 if +1 +2 if +1 +2 22 0 A B
  • 22. Exemplo 2: Apenas 1 Cenário Cobre 100% das Linhas assertEquals(24, sorveteria.precoSorvete (true, true, 2)); if +5 +1 +1 if +1 P 15 +1 if
  • 23. IF 17 20 IF +1 +2 IF +1 +2 P 0 public int precoSorvete(boolean premium, boolean casquinha, int coberturas) { int preco = 0; if (premium) { preco = 20; if (casquinha) { preco = preco + 2; if (coberturas > 1){ preco = preco + 2; } else { preco = preco + 1; } } else { preco = preco + 1; } } else { preco = 15 + 1 + 1; } return preco; } Ciclomática 4 +1 +1 Exemplo 3: Quantos Cenários São Necessários Para Cobrir 100% das Linhas?
  • 24. Exemplo 3: Quantos Cenários São Necessários Para Cobrir 100% das Linhas? if 17 20 if +1 +2 If +1 +2 P 0 A if 17 20 if +1 +2 If +1 +2 P 0 B if 17 20 if +1 +2 If +1 +2 P 0 D C
  • 25. Exemplo 3: São Necessários 4 Cenários Para Cobrir 100% das Linhas 17 = (false, false, 1) // 1 24 = (true, true, 2)) // 2 23 = (true, true, 1)) // 3 21 = (true, false, 2)) // 4 if 17 20 if +1 +2 If +1 +2 0 A if 17 20 if 21 +2 If 23 24 0 C D B
  • 26. Utilidade da Complexidade Ciclomática: Testabilidade Dependendo do algoritmo, a quantidade de caminhos únicos pode variar, mas o valor de complexidade ciclomática é o limite superior do número de cenários necessários para cobrir 100% das linhas e condições, se definidos corretamente
  • 27. É a métrica de software que mede a quantidade de quebras do fluxo linear de leitura ponderadas por nível de aninhamento dessas quebras. Mede o quão difícil é entender um código. Complexidade Cognitiva
  • 28. if 15 20 if +1 +2 if +1 +2 P 0 if +5 +1 +1 if +1 P 15 +1 if 1 2 if 17 20 if +1 +2 If +1 +2 P 0 3 Cognitiva Ciclomática 6 4 Cognitiva Ciclomática 3 4 Cognitiva Ciclomática 9 4
  • 29. Baixa “Sensibilidade” da Complexidade Ciclomática Método para cálculo da soma de todos os números primos até um máximo informado Método que retorna um texto relativo ao parâmetro passado através de um “switch” https://www.sonarsource.com/docs/CognitiveComplexity.pdf Ciclomática Cognitiva 4 7 Ciclomática Cognitiva 4 1
  • 30. Filosofia ● Foco no problema do programador (dificuldade de entendimento, não caminhos) ● Quebras no fluxo linear aumentam o esforço de entendimento ● Aninhamentos aumentam ainda mais o esforço gerado por uma quebra ● Incentivo a boas práticas, beneficiando as boas escolhas (e.g. “?.”, cláusula de guarda) ● Os testes passam ● Revela intenção ● Nenhuma duplicação ● Mínimo de elementos https://martinfowler.com/bliki/BeckDesignRules.html Clean Code
  • 31. Regras de Contagem Regra 1: Ignorar Abreviações Ignorar estruturas em que várias instruções podem ser abreviadas para apenas uma (incentiva boas práticas) Regra 2: Incrementar por Quebra de Fluxo (similar a Complexidade Ciclomática) Incrementar um ponto a cada quebra no fluxo linear do código + 1 ponto para: if, else if, else, operador ternário, switch, for, foreach, while, do while, catch, goto LABEL, break LABEL, continue LABEL, sequência de operadores lógicos (&&, || etc) e cada recurção encontrada Regra 3: Incrementar por Aninhamento Incrementar um ponto a cada nível de aninhamento de uma quebra de fluxo (além do ponto por quebra - R2) + 1 nível para: if, else if, else, operador ternário, switch, foreach, while, do while catch, métodos aninhados e métodos ou estruturas tipo lambda + 1 ponto para: if, operador ternário, switch, for, foreach, while, do while e catch.
  • 32. Exemplo da Regra 1 Ignorar estruturas em que várias instruções podem ser abreviadas para apenas uma Refatoração Cognitiva 0 Cognitiva 1 O cálculo privilegia boas práticas. O código à direita é mais fácil de entender “Safe Navigation Operator”
  • 33. Exemplo da Regra 2 e 3 IF 17 20 IF +1 +2 IF +1 +2 P 0 public int precoSorvete(boolean premium, boolean casquinha, int coberturas) { int preco = 0; if (premium) { preco = 20; if (casquinha) { preco = preco + 2; if (coberturas > 1){ preco = preco + 2; } else { preco = preco + 1; } } else { preco = preco + 1; } } else { preco = 15 + 1 + 1; } return preco; } Cognitiva 9 +1 +1 +1... +1 +2 +3 +1
  • 34. Particularidades da Regra 2: Sequências && e || Sequências de operadores iguais geram incremento de um ponto Operadores alternados contam um ponto cada um “a && b” = “a && b && c && d” “a || b” = “a || b || c || d” Uma sequência de “E” é lida como “todos esses” Uma sequência de “OU” é lida como “algum desses”
  • 35. Particularidades da Regra 2: Catch e Switch Catch gera o incremento de um ponto ● Um “catch” representa um desvio no fluxo da mesma forma que um “if” ● Incrementa um ponto independentemente de quantas exceções são tratadas catch (NullPointerException | IoException | IllegalArgumentException e) Switch gera o incremento de um ponto ● Apenas a variável de decisão precisa ser compreendida ● A quantidade de “cases” não aumenta a dificuldade de entendimento (é lido como “um desses”) ● Na C. Ciclomática cada “case” aumenta em um ponto!
  • 36. Momento Clean Code: O Que Está Ruim Abaixo? public int precoSorvete(boolean premium, boolean casquinha, int coberturas) { if (coberturas <= 3) { int preco = 0; if (premium) { preco = 20; if (casquinha) { preco = preco + 2; if (coberturas > 1){ preco = preco + 2; } else { preco = preco + 1; } } else { preco = preco + 1; } } else { preco = 15 + 1 + 1; } return preco; } return 0; }
  • 37. Muita Coisa Está Ruim! Inclusive Complexidade public int precoSorvete(boolean premium, boolean casquinha, int coberturas) { if (coberturas <= 3) { int preco = 0; if (premium) { preco = 20; if (casquinha) { preco = preco + 2; if (coberturas > 1){ preco = preco + 2; } else { preco = preco + 1; } } else { preco = preco + 1; } } else { preco = 15 + 1 + 1; } return preco; } return 0; } +1 +2 +3 +4 Cognitiva 13 +1 +1 +1 Problemas: ● Retorno sem semântica (Zero ou null) ● Mais difícil de ler (+ 1 IF) ● Pré condição misturada com código de negócio. Mais difícil testar e refatorar
  • 38. Cláusula de Guarda (Incentivo a Boas Práticas) public int precoSorvete(boolean premium, boolean casquinha, int coberturas) { if (coberturas > 3) { throw new IllegalArgumentException(“O máximo de coberturas é 3!); } int preco = 0; if (premium) { preco = 20; if (casquinha) { preco = preco + 2; if (coberturas > 1){ preco = preco + 2; } else { preco = preco + 1; } } else { preco = preco + 1; } } else { preco = 15 + 1 + 1; } return preco; } Cláusula de Guarda Cognitiva 10 Melhorias: ● Retorno somente com semântica ● Mais simples de entender ● Pré condição separada do negócio ● Exceção clara sobre mau uso do método
  • 39. Cláusula de Guarda (Incentivo a Boas Práticas) Cognitiva Ciclomática 6 4 +1 +2 +3
  • 40. Cláusula de Guarda (Incentivo a Boas Práticas) Cognitiva Ciclomática 3 4 +1 +1 +1
  • 41. Utilidade da Complexidade Cognitiva: Legibilidade 1. Score mais acurado para legibilidade 2. Contempla estruturas modernas (operador ?, lambdas) 3. Mede níveis acima de método (classe, pacote, sistema etc)
  • 42. Complexidade Ciclomática: Testabilidade Complexidade Cognitiva: Legibilidade Similaridades e Diferenças
  • 43. Resumo das Similaridades 1. Ambas se propõe a medir complexidade de um método ou função 2. Ambas incrementam a contagem por quebra de fluxo pontuando palavras reservadas (IF, For, While etc) 3. Ambas são suportadas por ferramentas de SAST 4. Ambas devem ser mantidas com valores baixos (menor = melhor)
  • 44. Resumo das Diferenças 1. C. Cognitiva mede além de métodos: classe, pacote e sistema 2. C. Ciclomática sempre incrementa “+1”; C. Cognitiva pontua extra por nível de aninhamento, mas só 1 p/ sequências (E, OU, Catch, Switch) 3. C. Cognitiva é nativa do Sonar, C. Ciclomática é padrão de mercado 4. Refatoração para melhorar complexidade de leitura é o melhor começo para sair da inércia da divida técnica. (mais fácil que teste de unid.)
  • 45. Complexidade Ciclomática ou Cognitiva? Eis a Questão... Complexidade Cognitiva Complexidade Ciclomática Perguntas...