Online, 10 de Junho de 2021
Douglas Siviotti
Sobre a apresentação
Assunto: Padrão de Projeto Cláusula de Guarda
Público Alvo: Desenvolvedores
Organização: 46 Slides em 4 partes (+- 30 minutos)
1. Definição
2. Além do Estilo
3. Complexidade e Testabilidade
4. Conclusão
Material de apoio desta apresentação:
https://github.com/siviotti/clausula-de-guarda
Douglas Siviotti
Desenvolvedor há mais de 20 anos, analista de
sistemas, especialista em engenharia de software
pela UFRGS, pós graduando em direito do uso e
proteção de dados pessoais pela PUC-MG, trabalha
como arquiteto de software no SERPRO desde
2005 e com qualidade de software desde 2012.
Atualmente atua como especialista em proteção de
dados pessoais atuando no suporte, especificação
de produtos, construção de processos e geração de
cursos e conteúdos relacionados ao tema no blog
artesoftware.com.br e na plataforma Udemy.
Cláusula
de Guarda
Clean Code
Complexidade
Ciclomática e
Cognitiva
Sobre o conteúdo
cláusula de guarda é uma
cláusula de guarda é uma
verificação de pré-condições
verificação de pré-condições
de um escopo local (método)
de um escopo local (método)
com uma possível saída
com uma possível saída
antecipada deste escopo
antecipada deste escopo
definição
definição
cliente: Olá, como faço para chegar na sala 3?
porteiro: Deixe-me ver seu tíquete, por favor.
cliente: Ops, acho que eu perdi.
porteiro: Sinto muito, o senhor não pode entrar.
objetivo: Assistir o filme
pré-condição: Ter e mostrar o tíquete de entrada
se a pré-condição não for atendida: O objetivo
principal que era assistir o filme não acontece
Cláusula
de Guarda
Cláusula
de Guarda
?
Cláusula de Guarda definição
A Cláusula de Guarda é uma checagem prévia de uma ou mais pré-condições
para execução de uma função ou método* que, caso a pré-condição não seja atendida,
provoca a saída antecipada do método ou função, separando as verificações de pré-
condições do código principal deste método. Dessa forma, o o método torna-se menos
complexo e mais fácil de ser lido, mantido e testado.
* ou construtor, inicializador etc
apenas
estilos
diferentes
?
Cláusula
de Guarda
cláusula de guarda é um
cláusula de guarda é um
recurso de design de código e
recurso de design de código e
não um mero estilo de
não um mero estilo de
codificação
codificação
além do estilo
além do estilo
Aspectos de Estilo de Código além do estilo
●
Abertura de chaves
●
Uso de espaços ou “tabs”
●
“Code Style” da equipe
●
Camel case, snake case etc
●
Pulo de linha, espaços
Aspectos Além do Estilo além do estilo
●
Legibilidade e Facilidade de Manutenção
●
Impactos e Efeitos Colaterais em Código Cliente
●
Complexidade e Testabilidade (parte 3)
Cláusula de Guarda além do estilo
Legibilidade e Facilidade de Manutenção além do estilo
Código 1
CLEAN CODE ALERT: Os comentários são desnecessários!
Legibilidade e Facilidade de Manutenção além do estilo
Código 2
Observações além do estilo
Código 1
Código 2
●
Um pouco menor, mas com IFs aninhados
●
Retorna “null” quando as pré-condições não são atendidas
●
Quando retorna “null” não fica claro qual pré-condição não foi
atendida
●
Pré-condições e código principal estão misturados
●
Um pouco maior, mas os IFs são independentes
●
Ou dá erro ou roda o código principal, sem ambiguidade (null)
●
Cada pré-condição não atendida gera uma exceção clara
●
Separa as pré-condições do código principal (divisão)
Impactos e Efeitos Colaterais em Código Cliente além do estilo
Código 1
Impactos e Efeitos Colaterais em Código Cliente além do estilo
Código 2
Impactos e Efeitos Colaterais em Código Cliente além do estilo
Código 1
Refatorado
CLEAN CODE ALERT: Código morto deve ser removido!
Efeitos Colaterais: Mensagem Errada além do estilo
Código 1
Refatorado
Mensagem
Equivocada
Pré-cond. 3
Pré-condição 1
não atendida
Observações além do estilo
Código 1
Código 2
●
Retornar “null” gerou uma confusão no código cliente
●
Obriga o programador a ler o código “bigDividir()”
●
Ao retornar uma exceção ao final melhorou, mas ainda gera
confusão sobre qual pré-condição não foi atendida
●
Executa divisão ou dispara exceção, sem dubiedade
●
O programador só precisa conhecer o “contrato”
●
Cada pré-condição não atendida gera uma exceção clara
complexidade é fator chave
complexidade é fator chave
para aumentar a facilidade de
para aumentar a facilidade de
entendimento/manutenção e a
entendimento/manutenção e a
testabilidade
testabilidade
complexidade
complexidade
Complexidade Ciclomática x Complexidade Cognitiva complexidade
Complexidade Ciclomática (CC) mede a quantidade de caminhos linearmente
independentes em um código fonte. Ou seja, é uma medida de quão difícil é testar uma
determinada unidade de código. CC baseia-se em um modelo matemático de grafos de
controle de fluxo.
Complexidade Cognitiva (C-Cog) mede a quantidade de quebras do fluxo linear de
leitura ponderadas pelo nível de aninhamento dessas quebras. Ou seja, é uma medida de
quão difícil é entender uma determinada unidade de código. C-Cog baseia-se em um
modelo de percepção subjetiva sobre a dificuldade de entendimento (não matemático).
E o que a cláusula de guarda tem com isso?
E o que a cláusula de guarda tem com isso?
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;
}
Conceito
Algorítimo Exemplo (Requisito 1) complexidade
Cognitiva
Ciclomática
3
4
+1...
+1
+1
+1
+1
+1
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;
}
Conceito
Algorítimo Exemplo com Aninhamento (Requisito 2) complexidade
Cognitiva
Ciclomática
9
4
+1
+1
+1...
+1
+2
+3
+1
+1
+1
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;
}
Requisito 1
Teste do
Requisito 1
Contratos e Efeitos Colaterais complexidade
Novo Requisito:
1. Somente sabores
premium podem ser
casquinha
2. Somente casquinha pode
ter mais de uma cobertura
Código 1
Requisito 2
Requisito 2
Código 2
IF de saída antecipada
IF de saída antecipada
Teste do
Requisito 2
Deveria dar erro nesses cenários impossíveis?
Observações complexidade
int preco = 15 + 1 + 1; // copo + 1 cob
if (!premium)return preco;
preco = 20 + 1 + 1; // copo + 1 cob
if (!casquinha) return preco;
return (coberturas > 1)
? preco + 2 : preco + 1;
+1
+1
+1
Refatoração
Cognitiva
Ciclomática
9
4
Cognitiva
Ciclomática
3
4
Testabilidade (4)
Leitura e Manutenção
Código 1 Código 2
●
Os “IFs de saída antecipada” se comportam de
forma semelhante à cláusula de guarda
●
O código 2 ficou menor e mais simples
Questões sobre Testabilidade complexidade
1. Se a complexidade ciclomática não se altera, será que o número
de cenários necessários é o mesmo ao utilizar cláusulas de guarda?
2. Como a cláusula de guarda impacta testes de unidade?
Questões sobre Testabilidade complexidade
1. Se a complexidade ciclomática não se altera, será que o número
de cenários necessários é o mesmo ao utilizar cláusulas de guarda?
Resposta: Depende do algoritmo, mas geralmente SIM
2. Como a cláusula de guarda impacta testes de unidade?
vejamos a seguir...
Complexidade Cognitiva Sem Cláusula de Guarda: 6 complexidade
Código 1
Cognitiva
Ciclomática
6
4
+1
+2
+3
Complexidade Cognitiva Usando Cláusula de Guarda: 3 complexidade
Código 2
Cognitiva
Ciclomática
3
4
+1
+1
+1
Questões sobre Testabilidade complexidade
1. Se a complexidade ciclomática não se altera, será que o número
de cenários necessários é o mesmo ao utilizar cláusulas de guarda?
Resposta: Depende do algoritmo, mas geralmente SIM
2. Como a cláusula de guarda impacta testes de unidade?
a. Se é mais fácil entender fica mais fácil testar
( se está difícil testar é porque está muito complexo)
b. É possível separar o código de guarda do principal
(ler e entender cada parte como um método separado)
... complexidade
Separação mental em duas partes:
1. Pré-condições
2. Código principal
1
2
... complexidade
1
2
Estes 7 cenários cobrem 100% das linhas
... complexidade
1
2
1
2
... complexidade
1
2
Cláusula de Guarda na API do Java (ArrayList) complexidade
1
2
1
1
2
Cláusulas de guarda “barulhentas” em
construtores ajudam a criar objetos com
estados válidos (IllegalStateException)
CONCLUSÃO conclusão
1. Cláusula de guarda não é questão de estilo, mas design de código
2. Melhora a leitura, entendimento e manutenção
- Separa as pré-condições do código principal
- Reduz a complexidade cognitiva (medida de qualidade Sonarqube)
3. Reduz ou evita impactos e efeitos colaterais em código cliente
4. Aumenta a testabilidade, sem reduzir o número de cenários
- Código menos complexo é mais fácil de testar (conclusão 2)
- Permite testes/cenários mais precisos e especializados
Programação Funcional X Orientação a Objetos
46/46
1 4
2 3 5
Cláusula
de Guarda
para encerrar...
Obrigado!
Douglas Siviotti
douglas.siviotti@gmail.com
artesoftware.com.br
- Complexidade
- Clean Code
Curso sobre Complexidade de Software na Udemy
https://www.udemy.com/course/complexidade-de-software/?referralCode=DBB27E501FADED8DA57C

TDC Connections 2021 Clausula de Guarda

  • 1.
    Online, 10 deJunho de 2021 Douglas Siviotti
  • 2.
    Sobre a apresentação Assunto:Padrão de Projeto Cláusula de Guarda Público Alvo: Desenvolvedores Organização: 46 Slides em 4 partes (+- 30 minutos) 1. Definição 2. Além do Estilo 3. Complexidade e Testabilidade 4. Conclusão Material de apoio desta apresentação: https://github.com/siviotti/clausula-de-guarda Douglas Siviotti Desenvolvedor há mais de 20 anos, analista de sistemas, especialista em engenharia de software pela UFRGS, pós graduando em direito do uso e proteção de dados pessoais pela PUC-MG, trabalha como arquiteto de software no SERPRO desde 2005 e com qualidade de software desde 2012. Atualmente atua como especialista em proteção de dados pessoais atuando no suporte, especificação de produtos, construção de processos e geração de cursos e conteúdos relacionados ao tema no blog artesoftware.com.br e na plataforma Udemy.
  • 3.
  • 4.
    cláusula de guardaé uma cláusula de guarda é uma verificação de pré-condições verificação de pré-condições de um escopo local (método) de um escopo local (método) com uma possível saída com uma possível saída antecipada deste escopo antecipada deste escopo definição definição
  • 5.
    cliente: Olá, comofaço para chegar na sala 3? porteiro: Deixe-me ver seu tíquete, por favor. cliente: Ops, acho que eu perdi. porteiro: Sinto muito, o senhor não pode entrar.
  • 6.
    objetivo: Assistir ofilme pré-condição: Ter e mostrar o tíquete de entrada se a pré-condição não for atendida: O objetivo principal que era assistir o filme não acontece
  • 7.
  • 8.
  • 9.
    Cláusula de Guardadefinição A Cláusula de Guarda é uma checagem prévia de uma ou mais pré-condições para execução de uma função ou método* que, caso a pré-condição não seja atendida, provoca a saída antecipada do método ou função, separando as verificações de pré- condições do código principal deste método. Dessa forma, o o método torna-se menos complexo e mais fácil de ser lido, mantido e testado. * ou construtor, inicializador etc
  • 10.
  • 11.
    cláusula de guardaé um cláusula de guarda é um recurso de design de código e recurso de design de código e não um mero estilo de não um mero estilo de codificação codificação além do estilo além do estilo
  • 12.
    Aspectos de Estilode Código além do estilo ● Abertura de chaves ● Uso de espaços ou “tabs” ● “Code Style” da equipe ● Camel case, snake case etc ● Pulo de linha, espaços
  • 13.
    Aspectos Além doEstilo além do estilo ● Legibilidade e Facilidade de Manutenção ● Impactos e Efeitos Colaterais em Código Cliente ● Complexidade e Testabilidade (parte 3)
  • 14.
    Cláusula de Guardaalém do estilo
  • 15.
    Legibilidade e Facilidadede Manutenção além do estilo Código 1 CLEAN CODE ALERT: Os comentários são desnecessários!
  • 16.
    Legibilidade e Facilidadede Manutenção além do estilo Código 2
  • 17.
    Observações além doestilo Código 1 Código 2 ● Um pouco menor, mas com IFs aninhados ● Retorna “null” quando as pré-condições não são atendidas ● Quando retorna “null” não fica claro qual pré-condição não foi atendida ● Pré-condições e código principal estão misturados ● Um pouco maior, mas os IFs são independentes ● Ou dá erro ou roda o código principal, sem ambiguidade (null) ● Cada pré-condição não atendida gera uma exceção clara ● Separa as pré-condições do código principal (divisão)
  • 18.
    Impactos e EfeitosColaterais em Código Cliente além do estilo Código 1
  • 19.
    Impactos e EfeitosColaterais em Código Cliente além do estilo Código 2
  • 20.
    Impactos e EfeitosColaterais em Código Cliente além do estilo Código 1 Refatorado CLEAN CODE ALERT: Código morto deve ser removido!
  • 21.
    Efeitos Colaterais: MensagemErrada além do estilo Código 1 Refatorado Mensagem Equivocada Pré-cond. 3 Pré-condição 1 não atendida
  • 22.
    Observações além doestilo Código 1 Código 2 ● Retornar “null” gerou uma confusão no código cliente ● Obriga o programador a ler o código “bigDividir()” ● Ao retornar uma exceção ao final melhorou, mas ainda gera confusão sobre qual pré-condição não foi atendida ● Executa divisão ou dispara exceção, sem dubiedade ● O programador só precisa conhecer o “contrato” ● Cada pré-condição não atendida gera uma exceção clara
  • 23.
    complexidade é fatorchave complexidade é fator chave para aumentar a facilidade de para aumentar a facilidade de entendimento/manutenção e a entendimento/manutenção e a testabilidade testabilidade complexidade complexidade
  • 24.
    Complexidade Ciclomática xComplexidade Cognitiva complexidade Complexidade Ciclomática (CC) mede a quantidade de caminhos linearmente independentes em um código fonte. Ou seja, é uma medida de quão difícil é testar uma determinada unidade de código. CC baseia-se em um modelo matemático de grafos de controle de fluxo. Complexidade Cognitiva (C-Cog) mede a quantidade de quebras do fluxo linear de leitura ponderadas pelo nível de aninhamento dessas quebras. Ou seja, é uma medida de quão difícil é entender uma determinada unidade de código. C-Cog baseia-se em um modelo de percepção subjetiva sobre a dificuldade de entendimento (não matemático).
  • 25.
    E o quea cláusula de guarda tem com isso? E o que a cláusula de guarda tem com isso?
  • 26.
    if +5 +1 +1 if +1 P 15 +1 if public int precoSorvete(booleanpremium, 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; } Conceito Algorítimo Exemplo (Requisito 1) complexidade Cognitiva Ciclomática 3 4 +1... +1 +1 +1 +1 +1
  • 27.
    if 17 20 if +1 +2 If +1 +2 P 0 publicint 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; } Conceito Algorítimo Exemplo com Aninhamento (Requisito 2) complexidade Cognitiva Ciclomática 9 4 +1 +1 +1... +1 +2 +3 +1 +1 +1
  • 28.
    public int precoSorvete(booleanpremium, 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; } Requisito 1
  • 29.
  • 30.
    Contratos e EfeitosColaterais complexidade Novo Requisito: 1. Somente sabores premium podem ser casquinha 2. Somente casquinha pode ter mais de uma cobertura Código 1 Requisito 2
  • 31.
    Requisito 2 Código 2 IFde saída antecipada IF de saída antecipada
  • 32.
    Teste do Requisito 2 Deveriadar erro nesses cenários impossíveis?
  • 33.
    Observações complexidade int preco= 15 + 1 + 1; // copo + 1 cob if (!premium)return preco; preco = 20 + 1 + 1; // copo + 1 cob if (!casquinha) return preco; return (coberturas > 1) ? preco + 2 : preco + 1; +1 +1 +1 Refatoração Cognitiva Ciclomática 9 4 Cognitiva Ciclomática 3 4 Testabilidade (4) Leitura e Manutenção Código 1 Código 2 ● Os “IFs de saída antecipada” se comportam de forma semelhante à cláusula de guarda ● O código 2 ficou menor e mais simples
  • 34.
    Questões sobre Testabilidadecomplexidade 1. Se a complexidade ciclomática não se altera, será que o número de cenários necessários é o mesmo ao utilizar cláusulas de guarda? 2. Como a cláusula de guarda impacta testes de unidade?
  • 35.
    Questões sobre Testabilidadecomplexidade 1. Se a complexidade ciclomática não se altera, será que o número de cenários necessários é o mesmo ao utilizar cláusulas de guarda? Resposta: Depende do algoritmo, mas geralmente SIM 2. Como a cláusula de guarda impacta testes de unidade? vejamos a seguir...
  • 36.
    Complexidade Cognitiva SemCláusula de Guarda: 6 complexidade Código 1 Cognitiva Ciclomática 6 4 +1 +2 +3
  • 37.
    Complexidade Cognitiva UsandoCláusula de Guarda: 3 complexidade Código 2 Cognitiva Ciclomática 3 4 +1 +1 +1
  • 38.
    Questões sobre Testabilidadecomplexidade 1. Se a complexidade ciclomática não se altera, será que o número de cenários necessários é o mesmo ao utilizar cláusulas de guarda? Resposta: Depende do algoritmo, mas geralmente SIM 2. Como a cláusula de guarda impacta testes de unidade? a. Se é mais fácil entender fica mais fácil testar ( se está difícil testar é porque está muito complexo) b. É possível separar o código de guarda do principal (ler e entender cada parte como um método separado)
  • 39.
    ... complexidade Separação mentalem duas partes: 1. Pré-condições 2. Código principal 1 2
  • 40.
    ... complexidade 1 2 Estes 7cenários cobrem 100% das linhas
  • 41.
  • 42.
  • 43.
    Cláusula de Guardana API do Java (ArrayList) complexidade 1 2 1
  • 44.
    1 2 Cláusulas de guarda“barulhentas” em construtores ajudam a criar objetos com estados válidos (IllegalStateException)
  • 45.
    CONCLUSÃO conclusão 1. Cláusulade guarda não é questão de estilo, mas design de código 2. Melhora a leitura, entendimento e manutenção - Separa as pré-condições do código principal - Reduz a complexidade cognitiva (medida de qualidade Sonarqube) 3. Reduz ou evita impactos e efeitos colaterais em código cliente 4. Aumenta a testabilidade, sem reduzir o número de cenários - Código menos complexo é mais fácil de testar (conclusão 2) - Permite testes/cenários mais precisos e especializados
  • 46.
    Programação Funcional XOrientação a Objetos 46/46 1 4 2 3 5 Cláusula de Guarda para encerrar... Obrigado! Douglas Siviotti douglas.siviotti@gmail.com artesoftware.com.br - Complexidade - Clean Code Curso sobre Complexidade de Software na Udemy https://www.udemy.com/course/complexidade-de-software/?referralCode=DBB27E501FADED8DA57C