SlideShare uma empresa Scribd logo
1 de 155
Baixar para ler offline
Clean Code na Prática
Conceitos de Clean Code Apresentados
em Exemplos de Código
Douglas Siviotti
Novembro de 2019 V1.1
Sobre esta Apresentação
1. Conteúdo: Clean Code (Código Limpo)
2. Área/Foco: Engenharia de Software, Desenvolvimento Ágil
3. Público alvo: Desenvolvedores
4. Conteúdo relacionado: OO, Programação Funcional, DDD, SOLID, GRASP
Organização (155 slides)
Parte 1 – Um Pouco de Filosofia
Parte 2 – Um Pouco de Teoria (Conceitos Relacionados)
Parte 3 – Clean Code na Prática em Exemplos de Código
Parte 4 – Laboratório de Refatoração
Código-fonte usado nesta apresentação:
https://github.com/refactown/cleancode
Cognição
Micro Design
Integração
Macro Design
Sintomas
comuns
equipe entregando cada vez menos
pontos a cada sprint
estimativas frustradas: o esforço
é sempre maior que o previsto
erros
frequentes em
produção
correção de um bug causa
outros problemas não previstos
incidentes resolvidos e o mesmo
erro voltando a aparecer
muito “To Do” espalhado pelo
código e/ou código morto
dificuldade de evolução ou
incorporação de novas
funcionalidades
Código Ruim
manutenção difícil
+ retrabalho e - produtividade
Código Ruim
manutenção difícil
+ retrabalho e - produtividade
Procrastinação
aversão a mudanças
criação de dívida técnica
Procrastinação
aversão a mudanças
criação de dívida técnica
Falta de Testes
design pobre e inflexível
falta de segurança p/ o dev
Falta de Testes
design pobre e inflexível
falta de segurança p/ o dev
Pressão
bugs, incidentes, pouco valor,
baixa evolução: insatisfação
Pressão
bugs, incidentes, pouco valor,
baixa evolução: insatisfação
ciclo
vicioso da
dívida
técnica
Código Limpo
fácil de entender e manter
expressa o negócio
Código Limpo
fácil de entender e manter
expressa o negócio
Refatoração
adaptação ao novo problema
tratamento de dívida técnica
Refatoração
adaptação ao novo problema
tratamento de dívida técnica
Teste de Unidade
guiando o design (feedback)
com boa cobertura
Teste de Unidade
guiando o design (feedback)
com boa cobertura
Entregas c/ Valor
evolução sustentável
cliente satisfeito
Entregas c/ Valor
evolução sustentável
cliente satisfeito
ciclo da
eficácia no
software
sob medida
Clean Code
Fazer código para ser lido e
entendido por outras pessoas
Clean Code
Fazer código para ser lido e
entendido por outras pessoas
Refatoração
adaptação ao novo problema
tratamento de dívida técnica
Teste de Unidade
guiando o design (feedback)
com boa cobertura
Entregas c/ Valor
evolução sustentável
cliente satisfeito
ciclo da
eficácia no
software
sob medida
Um PoucoUm Pouco
de Filosofiade Filosofia
Parte 1
Pequenas CoisasPequenas Coisas
ImportamImportam
“Deus está nos detalhes” “Menos é mais”
(Ludwig Mies van der Rohe)
Quem não faz bem as pequenas
coisas, não faz bem coisa alguma
código é detalhamentocódigo é detalhamento
dos requisitos e devedos requisitos e deve
expressar o negócioexpressar o negócio
código deve ser feito para ser lido por outra pessoacódigo deve ser feito para ser lido por outra pessoa
comunique,
não codifique!
código ruim geracódigo ruim gera
baixa produtividadebaixa produtividade
que gera código piorque gera código pior
seja um
glóbulo branco
prevenir é melhor
que remediar
por que
CódigoCódigo
Limpo?Limpo?
“elegante e eficiente
faz apenas uma coisa”
Bjarne Stroustrup
“simples e direto - legível”
Grady Booch
“inteligível ao seres humanos”
Dave Thomas
“escrito por alguém
que se importava”
Michael Feathers
“sem duplicação, expressivo,
pequenas abstrações”
Ron Jeffries
“a linguagem parece que foi
feita para o problema”
Ward Cunningham
O que é
A T I T U D EA T I T U D E
teoria da janela
quebrada
regra do
escoteiro
quando
programador
profissional
quem
quando
técnica, treino e tempotécnica, treino e tempo
livros de arte não
fazem um artista
trabalho artesanal
mas profissional
como
Um Pouco de Teoria*Um Pouco de Teoria*
*Oriunda de muita prática*Oriunda de muita prática
Parte 2
Título do Slide (Arial 18)
16/155
2.1 DDD: Negócio ao Código
2.2 Linguagem Onipresente
2.3 Princípio SRP
2.4 Princípio DRY
2.5 Indireção / Delegação
2.6 Lei de Demeter
2.7 Acoplamento e Coesão
2.8 Imutabilidade
2.9 OO + Funções Puras
2.10 Testes Tempestivos
2.11 Refatoração Tempestiva
2.12 Regras da Simplicidade
Conceitos
relacionados
O requisito está no código, mas muito código não vem do requisito
O domínio de um problema organiza os conceitos sobre os quais é baseada a solução de software
Foco no Negócio
Parte do código deve expressar o negócio
Isolamento do Domínio
O código de domínio é idiossincrático e particular
Infraestrutura à Parte
Tecnologias vêm e vão, o negócio permanece
Do Negócio ao Código Via DDD 2.1 Negócio ao Código
Domain
DDD e os Nomes das Coisas 2.2 Linguagem Onipresente
Ubiquos
Language
Service
Entity
Value
Object
Agregate
Factory
Model-driven
Design
Bounded
Context
RepositoryDomain
Events
Layered
Architecture
Core
Domain
Context
Map
Continuos
Integration
Linguagem Onipresente (Ubíqua)
- Termos e conceitos usados pelos desenvolvedores e pelos
especialistas no negócio
- Presente na fala de todos e no código de domínio
Contexto Delimitado
- Partes bem delimitadas de um domínio
- Candidatos a microsserviços
Tijolos de Construção
- Entidades, Objetos de Valor, Agregados
- Eventos de Domínio
- Serviços, Fábricas, Repositórios
Princípio da Responsabilidade Única (SRP) 2.3 Princípio SRP
“Cada módulo de um software deve ter um e apenas um motivo para mudar”
1
O que seria
apenas “uma”
responsabilidade?
Menos é Mais 2.4 Princípio DRY
DRY = Don’t Repeat Yourself
“Não Se Repita” (código, requisito, teste etc)
Toda parte do conhecimento deve ter
uma representação única e livre
de ambiguidades em todo o sistema
Problemas
- Mais trabalho: alterar mais vezes
- Mais risco: encontrar todos os lugares
- Mais teste: testar várias vezes a mesma coisa
- Mais esforço de comunicação
Indireção ou Delegação 2.5 Indireção / Delegação
SRP
Fazer apenas
uma coisa em
um certo lugar
SRP
Fazer apenas
uma coisa em
um certo lugar
DRY
Fazer apenas
em um lugar
uma certa coisa
DRY
Fazer apenas
em um lugar
uma certa coisa
Coisa única
em um
único lugar
“A”
Coisa única
em um
único lugar
“A”
Outra
coisa única
em um
único lugar
“B”
Outra
coisa única
em um
único lugar
“B”
Indireção ou Delegação
1. Não pode conter
2. Não pode copiar
3. Precisa referenciar
Indireção Indireção
Calculo de Frete Busca de EndereçoEfetuar Pedido
Lei de Demeter – Princípio do Menor Conhecimento 2.6 Lei de Demeter
Um módulo não deve enxergar o interior
dos objetos que ele manipula
Um método “m” de uma classe “C” só deve chamar:
- Objetos do tipo “C”
- Parâmetros passados para o método “m” (e.g. “x: P”)
- Um objeto criado pelo próprio método “m”
- Variáveis de instância da classe “C” (e.g. “a: A”)
Train Wreck (Acidente de Trem): x.getY().getZ()
“Você não manda as pernas do cachorro andarem e sim o cachorro”
Classe “C”
Atributo a: A
Método “m” (x: X)
Classe X
Atributo y : Y
Classe Y
Atributo z : Z
Baixo Acoplamento e Alta Coesão 2.7 Acoplamento e Coesão
Alto Acoplamento
Baixa Coesão
(entre classes)
Poucas classes e grandes
Mais dependência por classe
Maior conhecimento
Baixo Acoplamento
Alta Coesão
(entre classes)
Muitas classes e pequenas
Menos dependência por classe
Menor conhecimento
Coesão de uma Classe:
- Poucas variáveis de instância
- Cada método manipula uma ou mais
Uma classe pouco coesa sugere
que uma nova classe deve “nascer”
Quanto Mais Imutável Melhor 2.8 Imutabilidade
Evite Surpresas
Imutabilidade é uma defesa contra
efeitos colaterais
Vantagens
- Mais seguro e confiável
- Mais legível:
minimiza testes e garantias
diminui o código por tabela
- Paralelismo e escalabilidade
private final int idade;
Quanto Mais Puro Melhor 2.9 OO + Funções Puras
Função Pura
1. Para um certo Input sempre retorna o mesmo Output
2. Não causa nenhum efeito colateral
3. Não depende de nenhum dado externo (autocontida)
Vantagens
- Mais simples e menores
- Mais fácil de entender e testar
Quando usar em código OO?
Sempre que possível
Em muitas situações não é possível: BD, integração, estados etc
Possível em regras de negócio, métodos utilitários, internos etc
Function
Input
Output
IMUTABILIDADE
- efeitos colaterais
TDD e Testes Tempestivos 2.10 Testes Tempestivos
TDD – Test Driven Development
(Desenvolvimento Guiado por Testes)
- Escreve um teste que falha antes do código produtivo
- Faz o teste passar ao construir o código produtivo
- Refatora o código até o teste falhar (ou não)
Testes Tempestivos (TDD inclusive)
(teste que ajuda na construção, logo cedo)
1. Atividade de engenharia (código e design)
2. Feedback rápido sobre o código testado (erra cedo)
3. Gera código limpo através da “dificuldade” de testar
4. Antecipa o custo gasto em correções e debug
5. Ainda serve como teste de regressão
Refatora
Falha
Passa
Ciclos
Curtos
Refatoração Tempestiva 2.11 Refatoração
“Refatoração (refactoring) é a disciplina técnica
para reestruturar um determinado código,
alterando sua estrutura interna sem mudar seu
comportamento externo”
Martin Fowler
Problema Inicial Solução Inicial
Problema Refinado
Refatoração
Mudança
Solução Final
Validar Solução
Refinamento
Ciclo de
Sprint
Ajuste da solução em função de:
- uma nova visão sobre o problema
- preparar para uma evolução ou mudança
Pequenas mudanças que fazem
diferença no longo prazo
Quatro Regras da Simplicidade (Martin Fowler : Kent Beck) 2.12 Simplicidade
Testes Tempestivos
Refatoração Tempestiva
https://martinfowler.com/bliki/BeckDesignRules.html
Conceitos Relacionados Conceitos
DDDDDD Linguagem
Onipresente
Linguagem
Onipresente
Indireção
Abstração, especialização
Indireção
Abstração, especialização
Lei de Demeter
Mínimo conhecimento
Lei de Demeter
Mínimo conhecimento
Princípio SRP
Responsabilidade Única
Princípio SRP
Responsabilidade Única
Princípio DRY
Não Se Repita
Princípio DRY
Não Se Repita
Acoplamento
e Coesão
Acoplamento
e Coesão
Funções Puras
OO ou funcional
Funções Puras
OO ou funcionalInfraInfra
DomínioDomínio
AppApp
Refatoração
Tempestiva
Refatoração
Tempestiva
Teste
Tempestivo
Teste
Tempestivo
4 Regras da
Simplicidade
4 Regras da
Simplicidade
Imutabilidade
- efeitos colaterais
Imutabilidade
- efeitos colaterais
Clean
Code
Clean
Code
PráticaPrática
Parte 3
Título do Slide (Arial 18)
31/155
3.1 Código Limpo
3.2 Nomes Significativos
3.3 Comentários (capítulo 4)
3.4 Formatação (capítulo 5)
3.5 Funções (capítulo 3)
3.6 Objetos e E. de Dados
3.7 Tratamento de Erro
3.8 Fronteiras (Limites)
3.9 Testes de Unidade
3.10 Classes
3.11 Sistemas Complexos
3.12 Simplicidade
Prática
- filosofia
- bad smell
- boa prática
- exemplo
- exercício
Cognição
Entendimento e leitura
Integração
Contratos e expectativas
Macro Design
Escala e expansão
Micro Design
Estado e comportamento
Código LimpoCódigo Limpo
(Visão Geral)(Visão Geral)
Parte 3.1Parte 3.1
Filosofia sobre Código Limpo (Visão Geral) 3.1 Código Limpo
- O código não fica nem se mantém limpo sozinho
- Todos na equipe devem praticar e cobrar
- Manter o código limpo é uma atividade diária
- Funciona como na “Teoria das janelas quebradas”
- Atitude é mais relevante do que “patrocínio”
- Sempre dá pra começar (regra do escoteiro)
- Ler e entender consome mais tempo que escrever
- Precisa de tempo, técnica e treino pra fazer bem
Código Ruim 3.1 Código Limpo
Problemas
- Nomes ruins
- Função grande e complexa (SRP)
- Comentários questionáveis
- Formatação inexistente
Dificuldades
- Legibilidade: confuso
- Testabilidade: alta complexidade
Código Menos Ruim 3.1 Código Limpo
Problemas
- Nomes ruins
- Função grande e complexa (SRP)
- Comentários questionáveis
- Formatação inexistente
Dificuldades
- Legibilidade: confuso
- Testabilidade: alta complexidade
Código Melhorado (Refatorado) 3.1 Código Limpo
O que pode melhorar?
Possíveis Melhorias 3.1 Código Limpo
Lançar Exceção
Constantes
Enum “Premio”
Classe Separada
NomesNomes
SignificativosSignificativos
Parte 3.2Parte 3.2
Filosofia sobre Nomes 3.2 Nomes Significativos
- Nomes são muito importantes (especialmente em OO)
- Use nomes que revelam seu propósito
- Evite informações erradas (itemList: Map)
- Faça distinções significativas (evite a1, a2 a3...)
- Nomes pronunciáveis e passíveis de busca
- Evite codificações (e.g. notação húngara e similares)
- classes = substantivos, métodos = verbos
- Selecione uma palavra por conceito (get, set, find)
- Nomes do problema (Pedido, Item) e da solução (DAO)
- Adicione ou evite contexto quando necessário
Bad Smell 3.2 Nomes Significativos
Problemas
- Nomes genéricos “i”, “x”, “d” etc
- Nomes impronunciáveis
- Número Mágico (perdido no código)
- Notação Húngara
- Interface prefixada
- Nome com contexto redundante
Boa Prática 3.2 Nomes Significativos
Alternativas
- Nomes que revelam propósito
- Nomes pronunciáveis
- Constantes para número mágico
(passíveis de busca)
- Sem Notação Húngara
- Interface = Conceito
- Nomes com o mínimo necessário
Problema x Solução 3.2 Nomes Significativos
Problema
Solução
Modelo de Exemplo 3.2 Nomes Significativos
Nomes a partir do domínio do problema (Pedido, Item etc)
Nomes a partir do domínio da solução (Controller, Delegate, DAO)
Classes = Substantivos, Métodos = Verbos
Nomes pronunciáveis e passíveis de busca
Parte 3.3Parte 3.3
ComentáriosComentários
Filosofia sobre Comentários 3.3 Comentários
“Qualquer um pode escrever código que o computador
entenda. Bons programadores escrevem códigos que os
humanos entendem.”
Martin Fowler
- Comentários são a última opção do programador
- O programador deve expressar-se no código
- Comunique, não codifique (outros devem ler)
- Comentário pode estar compensando código ruim
- Alguns comentários são bons ou necessários
Explique-se no Código 3.3 Comentários
Alguns comentários existem para explicar código ruim.
Um comentário deve explicar “o porquê” e nunca “o que”
Não comente, refatore!
Comentários Bons: Legais e APIs Públicas 3.3 Comentários
Comentários Bons: Alguns “TODO”, Alertas e Destaques 3.3 Comentários
Comentário Ruim: Murmúrio e Redundância 3.3 Comentários
Comentário Ruim: Código Morto e/ou com Autoria 3.3 Comentários
Use o controle de versão!
Outros Comentários Ruins 3.3 Comentários
- Ruidosos, muito longos ou repetitivos
- Imperativos (e.g. em todas as funções)
- Marcadores de Posição //////////////// ou ************
- Ao lado de chaves de fechamento (e.g. //for)
- Comentários em HTML
- Informações excessivas
- Conexões nada óbvias
- Cabeçalhos de funções (prefira um bom nome)
- Javadoc em código não público
Parte 3.4Parte 3.4
FormataçãoFormatação
Filosofia sobre Formatação 3.4 Formatação
- Atenção ao “code convention” da linguagem
- O projeto deve ter um “code style” (bom ou ruim)
- Qualquer “code style” é melhor que nenhum
- A formatação automática evita muitas brigas
- Formatação vertical
Metáfora do jornal, distância vertical, espaçamento e
continuidade vertical
- Formatação horizontal
Indentação, espaçamento e continuidade horizontal
Formatação Vertical: Metáfora do Jornal 3.4 Formatação
Formatação Vertical: Continuidade e Espaçamento Vertical 3.4 Formatação
Linhas de código relacionadas
devem permanecer unidas
Pensamentos completos devem ser
separados por espaços em branco
Formatação Vertical: Distância Vertical 3.4 Formatação
Declaração de Variável
O mais próximo possível de
onde será usada
Variáveis de Instância
Antes dos métodos
Funções Dependentes
Verticalmente próximas
Afinidade Conceitual
Mesma convenção de nomes
atuam na mesma tarefa
devem ficar próximas
Formatação Horizontal 3.4 Formatação
Evite
- Espaçamentos manuais
- Indentação do “seu gosto”
- Mais de 120 caracteres por linha
Deixe a IDE trabalhar
- Espaçamentos automáticos
- Indentação padrão
- Quebras de linha
Regra da Tela 3.4 Formatação
<= 20
Cabe na tela
<= 500
100-120
Cabe na tela
Code Convention + Regra da Equipe 3.4 Formatação
Mantenha a paz no seu projeto: tenha um “code style” combinado pela equipe
Parte 3.5Parte 3.5
FunçõesFunções
Filosofia sobre Funções 3.5 Funções
- Funções devem ser pequenas (<= 20 linhas)
- Funções devem fazer apenas uma coisa
- Devem ter nomes descritivos do que fazem
- Somente um nível de abstração por função
- Funções devem ter poucos parâmetros
- Efeitos colaterais devem ser evitados ao máximo
- Quanto mais funções puras, melhor
- Quanto mais autocontida mais fácil de testar
Clean
Code
(2008)
Programação
Funcional
(1958)
Pura
Sem efeitos colaterais
1 nível de abstração
Faz apenas 1 coisa
Pequena
Clean Code + Programação Funcional 3.5 Funções
Regra 1 3.5 Funções
Faz Apenas 1 Coisa
- Nomes, comentários e formatação são importantes para a
leitura, mas as funções são o que o programa realmente faz
- É melhor ler e entender uma coisa de cada vez
- É melhor testar uma coisa de cada vez
1 Nível de Abstração
- Cada conceito em seu lugar apropriado
Abstração é a capacidade de separar o essencial do que
não é essencial. Separar conceitos dos detalhes.
3.5 FunçõesExemplo de Função “Suja”
Grande (34 linhas)
Faz muitas coisas:
1. Valida os números apostados
2. Verifica se está entre 6 e 15
3. Sorteia 6 números
4. Conta os acertos
5. Calcula o prêmio
Vários níveis de
abstração
1
2
3
4
5
Exemplo de Função “Limpa” 3.5 Funções
Pequena (11 linhas)
Faz 1 coisa:
1. Valida os números apostados
2. Verifica se está entre 6 e 15
3. Sorteia 6 números
4. Conta os acertos
5. Calcula o prêmio
1 nível de abstração
1 coisa e 1 nível de abstração
Indireção
Regra Decrescente 3.5 Funções
Indireção Nível de abstração 1
Nível de abstração 2
Leitura
de cima
para
baixo
Nomes
descritivos
do que
fazem
Switch Highlander (Java) 3.5 Funções
Um “Switch” deve estar em
uma classe de nível mais
baixo de abstração e
nunca ser repetido
Opção procedural
Opção polimórfica
Switch Highlander (Kotlin) 3.5 Funções
Um “Switch” deve estar em
uma classe de nível mais
baixo de abstração e
nunca ser repetido
Opção procedural
Opção polimórfica
Fibonacci (Funções Puras) 3.5 Funções
1. Para um certo Input sempre retorna o mesmo Output
2. Não causa nenhum efeito colateral
3. Não depende de nenhum dado externo (escopo)
Pedra, Papel e Tesoura: Especificação via Teste de Unidade 3.5 Funções
R (Rock/Pedra) vence S (Scissors/Tesoura)
S (Scissors/Tesoura) vence P (Paper/Papel)
P (Paper/Papel) vence R (Rock/Pedra)
Pedra, Papel e Tesoura: Contrato 3.5 Funções
Cabeçalho da Função:
pedraPapelTesoura(char,char):int
Contrato da Função:
- Recebe dois caracteres (R, P ou S)
- Se empata retorna 0
- Se o primeiro ganha retorna -1
- Se o segundo ganha retorna 1
- Se um dos caracteres é inválido gera uma
exceção “IllegalArgumentException”
(melhor que código de erro)
- R vence S, S vence P, P vence R
Pedra, Papel e Tesoura (Kotlin) 3.5 Funções
1 Nível de abstração
Faz apenas 1 coisa
Prefira exceções a retorno de códigos de erro!
É uma função pura?
Pedra, Papel e Tesoura (Java) 3.5 Funções
É uma função pura?
Parâmetros 3.5 Funções
Função Mônade P1
Função Díade
Função Tríade P1 P2 P3
P1 P2
A quantidade de parâmetros deve ser a
menor possível. Se a quantidade de
parâmetros é muito grande, pode ser usado
um objeto como parâmetro.
Objeto como Parâmetro
O parâmetro tem suas regras e seus próprios conceitos
Parâmetros Seletores e de “Saída” 3.5 Funções
Parâmetro de “Saída”
Saída deve ser no retorno
Parâmetro Seletor
É preferível dividir em duas funções
Um parâmetro seletor já indica logo
na assinatura que uma função faz
duas coisas. O ideal é fazer
duas funções separadas.
Separação Comando-Consulta 3.5 Funções
Comando + Consulta
Apenas Consulta
Apenas Comando
As funções devem somente
fazer ou responder
algo, mas não ambos. Ou altera
o estado de um objeto ou
retorna informação sobre ele.
Tratamento de Erro é 1 Coisa Só 3.5 Funções
O “try” deve ser a primeira linha da função e não deve
haver nada depois fim do bloco “try/catch/finally”
O Cerne de Boas Funções 3.5 Funções
Evite Repetição (DRY)
- Indireção, extração etc podem gerar duplicação
- Funções menores e especializadas requerem reúso (SRP)
Faça e Refaça com Confiança
- Comece fazendo funcionar e depois refatore
- Tenha cobertura de testes para ter confiança
Funções são verbos do domínio
- Uma hierarquia de funções conta uma estória
- Níveis de abstração ajudam na leitura da estória
Objetos e EstruturasObjetos e Estruturas
de Dadosde Dados
Parte 3.6Parte 3.6
Filosofia sobre Objetos e Estruturas de Dados 3.6 Objetos e E. de Dados
Os objetos usam abstrações para esconder seus
dados e expõem funções que operam sobre eles
Estruturas de dados expõem seus dados e não
possuem funções significativas (get/set = acessores)
- Objetos buscam o menor conhecimento
- Estruturas de dados (DTO) buscam imutabilidade
Estruturas de Dados nas Linguagens 3.6 Objetos e E. de Dados
Kotlin tem uma palavra reservada para definir uma estrutura
de dados: “data”. A sintaxe deixa clara a diferença entre
uma estrutura de dados e demais classes/objetos
PedidoDTO 3.6 Objetos e E. de Dados
Objeto ou Estrutura de Dados?
Pedido 3.6 Objetos e E. de Dados
Objeto ou Estrutura de Dados?
Pedido Com Mais Encapsulamento 3.6 Objetos e E. de Dados
Objeto ou Estrutura de Dados?
Feature Envy (Inveja de Funcionalidade) 3.6 Objetos e E. de Dados
https://martinfowler.com/bliki/TellDontAsk.html
Um objeto tem “inveja” da funcionalidade de
que deveria ser implementada em outro objeto
No exemplo abaixo, o primeiro “IF” tem inveja da funcionalidade
que diz se um pedido é válido, mas pedido é um OBJETO
Numa ESTRUTURA DE DADOS isso não seria problema
Princípio “Tell
Don’t Ask”
Indireção
Sobre uma Estrutura de Dados
Sobre um Objeto
Procedural x Orientado a Objetos (OO) 3.6 Objetos e E. de Dados
E se precisar calcular o perímetro?
(as estruturas de dados não serão afetadas)
E se precisar criar a classe triângulo?
Espectros de Objetos / Estrutura de Dados 3.6 Objetos e E. de Dados
Encapsulamento
Estrutura
de Dados ObjetosHíbridos
Imutabilidade
Facilita a adição de novas funcionalidades
Facilita a adição de novas classes Triângulo
Perímetro
Feature Envy no Modelo de Figuras (Shape) 3.6 Objetos e E. de Dados
Feature Envy + Efeitos Colaterais 3.6 Objetos e E. de Dados
Lei de Demeter sobre Objetos 3.6 Objetos e E. de Dados
x = a.getB().getC().getD()x = a.b.c.d
Train Wrecks
(Acidente de Trem)
a
b c d
NullPointer
Exception
(null)
Estrutura de Dados Objetos
- Imutabilidade
- Proibição de “null”
- Estados mutáveis
- Possibilidade de “null”
x = a?.b?.c?.d
(Navegação Segura)
Parte 3.7Parte 3.7
Tratamento de ErroTratamento de Erro
Filosofia sobre Tratamento de Erro 3.7 Tratamento de Erros
- Use exceções em vez de retornar códigos
- Prefira exceções não verificadas (unchecked)
- Forneça exceções com contexto e sem abafamento
- Pense no design do “try-catch-finally” antes
- Defina exceções pensando no chamador (e.g. Libs)
- Cada “catch” faz apenas uma coisa
- Não retorne nem passe “null”
- Dê preferência às exceções já fornecidas (efective java)
Código de Exceção Ruim 3.7 Tratamento de Erros
Problemas
- Não retorna uma exceção
- Abafa exceção do Gson
- Retorna “null”
- Imprime direto no console
Consequências
- Contrato baseado em “null”
- Omissão do erro raiz (causa)
- Força a testar nulidade:
kotlin: ?.
java: if (result != null)
- Log inadequado e ineficiente
Código de Exceção com Perda da Causa Raiz 3.7 Tratamento de Erros
Problemas
- Não retorna uma exceção
- Abafa exceção do Gson
- Retorna “null”
- Imprime direto no console
Consequências
- Contrato baseado em “null”
- Omissão do erro raiz (causa)
- Força a testar nulidade:
kotlin: ?.
java: if (result != null)
- Log inadequado e ineficiente
Código Melhorado (Repassando a Causa Raiz) 3.7 Tratamento de Erros
O que acontece se “json” ou “clazz” forem nulos?
Por que nunca se deve passar “null” como parâmetro?
Código de Teste Obtendo a Causa Raiz (Gson) 3.7 Tratamento de Erros
Questão Sobre a Criação de Classes de Exceção 3.7 Tratamento de Erros
Existe realmente a necessidade de criar a exceção “JsonException”?
Não seria melhor usar as exceções prontas do Gson?
Parte 3.8Parte 3.8
FronteirasFronteiras
Filosofia sobre Fronteiras 3.8 Fronteiras
- Código de terceiro quase sempre é “infraestrutura”
- Infraestrutura deve ser isolada do negócio
- Testes de aprendizado são uma boa dica
Estudo de Caso do Parsing de Json 3.8 Fronteiras
Necessidade
Fazer parsing e serialização de Json
em várias partes da aplicação
Inicialmente usando o “Gson”
Opcionalmente pode ser usado outra
biblioteca como “Jackson”
A infraestrutura deve ser isolada
Domain
ControllerController
JsonParser
Interface
toJson()
fromJson()
JsonParser
Interface
toJson()
fromJson()
GsonParserGsonParser
JacksonParserJacksonParser
Estudo de Caso do Parsing de Json 3.8 Fronteiras
Terceiros Infraestrutura
Infraestrutura
Aplicação
API de Terceiros
Estudo de Caso do Parsing de Json 3.8 Fronteiras
GsonParserGsonParser
JacksonParserJacksonParser
Parser Baseado no Gson 3.8 Fronteiras
GsonParserGsonParser
Encapsula o Gson
É um JsonParser
Injetando Dependência 3.8 Fronteiras
Criação manual
Injeção de dependência
Controller
Parser
Interface
toJson()
fromJson()
GsonParser
JacksonParser
Teste de Aprendizado do Gson 3.8 Fronteiras
Parte 3.9Parte 3.9
Testes de UnidadeTestes de Unidade
Filosofia sobre Testes de Unidade 3.9 Testes de Unidade
- Teste de unidade dá feedback sobre o design
- O feedback deve chegar o quanto antes
- TDD é uma boa opção para tornar mais fácil
- Testes de unidade são atividade de construção
- Cobertura de testes provê confiança
- Refatoração sem cobertura pode ser uma aventura
- Teste também é código e deve ser limpo
Cenário de Construção com TDD em 3 Iterações 3.9 Testes de Unidade
Requisitos do Contador de Constantes
1. Criar uma função que conte todas as constantes inteiras de uma
classe passada como parâmetro (atributos estáticos e “final”)
2. Parâmetro “null”, classes abstratas e enuns são ignorados e
deve ser retornado “-1” como resultado da função
3. A contagem deve incluir todas as superclasses
As 3 Regras do TDD 3.9 Testes de Unidade
Refatora
Falha
Passa
1. Você não pode escrever nenhum código até ter escrito um
teste que detecte uma possível falha.
2. Você não pode escrever mais testes de unidade do que o
suficiente para detectar a falha – não compilar é não ter
efeito.
3. Você não pode escrever mais código do que o suficiente
para passar nos testes.
TDD – Escrever a Primeira Versão do Teste e Falhar 3.9 Testes de Unidade
Falha
1. Criar uma função que conte
todas as constantes inteiras de
uma classe (estáticos e “final”)
TDD – Escrever o Código Real e Passar 3.9 Testes de Unidade
Passa
TDD – Refatorar o Código Real e Passar (Apenas Melhoria) 3.9 Testes de Unidade
Passa
Extração da lista
Extração do método
TDD – Refatorar o Teste para o Requisito 2 (Iteração 2) 3.9 Testes de Unidade
2. Classes abstratas e enuns são ignorados (retornar -1), inclusive “null”
Refatora
TDD – Teste Refatorado Vai Falhar 3.9 Testes de Unidade
Falha
Falha Aqui
TDD – Ajuste do Código para Atender o Teste (Iteração 2) 3.9 Testes de Unidade
Passa
Adição do requisito 2
TDD – Refatorar o Teste para o Requisito 3 (Iteração 3) 3.9 Testes de Unidade
3. A contagem deve incluir as superclasses
Refatora
TDD – Teste Refatorado Vai Falhar (Iteração 3) 3.9 Testes de Unidade
Falha
Tem 2 constantes
Falha Aqui
TDD – Ajuste do Código para Atender o Teste (Iteração 3) 3.9 Testes de Unidade
Passa
Adição do requisito 3
Parte 3.10Parte 3.10
ClassesClasses
Filosofia sobre Classes 3.10 Classes
- Classes devem ser pequenas
- Devem ter somente uma responsabilidade (SRP)
- Ter apenas um motivo para mudar
- Devem ter coesão interna*
* Poucas variáveis de instância
* Cada método manipula uma variável ou mais
- Devem encapsular seus dados ao máximo
- Devem ter baixo acoplamento a outras classes
Jogando “Pedra, Papel e Tesoura” 3.10 Classes
Requisitos do Melhor de 3 (Pedra, Papel e Tesoura)
1. Criar uma simulação de dois jogadores jogando “pedra, papel e
tesoura” por um número variável de rodadas (3, 5 etc).
2. O jogo deve parar se um jogador já for o vencedor antes da última
rodada (cenário de vitória antecipada).
3. Ao final deve ser indicado o vencedor (ou empate) e listados os
resultados de todas as rodadas.
Código Fornecido 3.10 Classes
Enum
Mão: Possibilidades de
escolha (Pedra, Papel ou
Tesoura)
Código Fornecido 3.10 Classes
Enum
Resultado: Resultado em relação
ao primeiro jogador:
Perde: -1
Empata: 0
Vence: 1
Abstração de pedraPapelTesoura
Código Fornecido 3.10 Classes
Enum
ResultadoJogada: Resultados
de um match (Primeiro Vence,
Empate ou Segundo Vence)
Implementação Procedural Simples 3.10 Classes
pedraPapelTesoura(char,char):int
Problemas
- Um método faz tudo
- Muitos conceitos juntos:
“Jogador”, “Match”, “Resultados”
- “Rodadas” constantes
- Nomes “hard coded”
- Não pára em vitória antecipada
Questões
Como se livrar do código legado
pedraPapelTesoura ?
A solução é muito procedural?
Como testar isso?
2 escolhas aleatórias
Modelo Lógico: Possível Solução OO 3.10 Classes
Níveis de Abstração
- O Jogo e os resultados
- Uma Disputa entre jogadores
- O resultado de uma disputa
- Jogador com nome e escolha
- A opção de jogada
Modelo Lógico: Análise dos Conceitos do Jogo 3.10 Classes
Inicialização e Contexto
Conceito: 1 JogadorConceito: 1 Disputa
Conceito: O Jogo em si
Várias rodadas e resultado
Código “Legado”: Lógica do jogo
Conceito: Resultado de uma Disputa
Abstração sobre -1,0,1
Opções do Jogo: R, P e S
Implementação OO - Main 3.10 Classes
Instanciação de
dependências
Inicialização
em “jogar()”
I/O = Efeito colateralI/O = Efeito colateral
Classe MelhorDeTres 3.10 Classes
Responsabilidade: representa um jogo de
“Pedra, Papel e Tesoura” com a definição
do número de rodadas (3 por padrão) e
armazena os resultados (estado)
API
- Executa o jogo (play)
- Retorna se tem vencedor
- Retorna o vencedor (se houver)
- Retorna os resultados
Delega para a classe Match o
conhecimento sobre a disputa entre dois
jogadores e seu resultado
Indireção para Jogada
Requisito número 2
Dependência será resolvida
via construtor
Classe JogadaLegada (Implementa Jogada) 3.10 Classes
Representa uma disputa entre dois jogadores e seu resultado (imutável)
API: Executa a disputa (play) e gera um resultado
Delega para os jogadores a escolha da “mão” que será jogada. Delega para a função
rockPaperScissors a lógica de quem venceu a disputa com base nestas escolhas
Classe Jogador 3.10 Classes
Representa um jogador que deve fazer uma escolha de qual mão usar na disputa
Delega para Mao a escolha de forma aleatória, mas encapsula esta decisão
O jogador poderia ser criado com a escolha já feita anteriormente
Solução OO x Procedural 3.10 Classes
A solução OO tem mais código, mas cada parte é mais fácil de entender que o todo
Permite testes de unidade por classe
Cada abstração está em uma classe
Cada classe tem uma responsabilidade
A necessidade de manutenção tende a impactar somente uma parte do código
Refatoração: Livrando-se do Código Legado 3.10 Classes
Como remover pedraPapelTesoura?
Qual classe deve conhecer esta regra
de quem vence quem?
Como implementar a regra de forma a
gerar o menor impacto possível?
Qual seria o impacto de alterar e
testar na solução procedural?
Especificação da Regra “Pedra/Papel/Tesoura” Legada 3.10 Classes
Especificação da Regra “Pedra/Papel/Tesoura” OO 3.10 Classes
Responsabilidade da Classe “Mao” 3.10 Classes
Código expressivo sobre a regra do jogo
Função (API) que externaliza a regra
Impacto: Nova Classe Implementando “Jogada” 3.10 Classes
Implementação alternativa de “Jogada” livre do código legado
O método “jogar” expressa o negócio de forma simples e elegante
Função (API)
que externaliza
a regra
JogadaLegada x JogadaSimples (Nova) 3.10 Classes
- Mais semântico e claro
- Dispensa o enum “Resultado”
- Delega para o método “vence” de
uma outra classe (“Mao”)
Kotlin infix
Impacto da Refatoração na Classe “Main” 3.10 Classes
Criação da classe “JogadaSimples” (Troca de “JogadaLegada” por “JogadaSimples”)
A classe “MelhorDeTres” não teve nenhum impacto e ainda recebe a dependência
Responsabilidades:
- Criar Jogadores
- Criar Jogada
- Inicializar o Jogo
...
- Conexão de Banco ?
- I/O, Integrações ?
Parte 3.11Parte 3.11
SistemasSistemas
Filosofia sobre Testes de Unidade 3.11 Sistemas Complexos
- Sistemas precisam de separação de preocupações
- Separe a inicialização do uso de um sistema
- Sistemas beneficiam-se do uso de uma DSL
Modularização e Separação de Preocupações 3.11 Sistemas Complexos
- Criação de objetos e escopos superiores
- Conexão com BD, I/O e efeitos colaterais DDD e Preocupações Transversais
Main main()
Negocio
Módulo A
Domain Service
Módulo B
Função X1
Classe X Função X2
Função X3
Factory Create
Módulo C
Função Y1
Classe Y Função Y2
Função Y3
Repository Save
Log
Segurança
BD
I/O
Inicialização e Contexto
Conceito: 1 JogadorConceito: 1 Disputa
Conceito: O Jogo em si
Várias rodadas e resultado
Código “Legado”: Lógica do jogo
Conceito: Resultado de uma Disputa
Abstração sobre -1,0,1
Opções do Jogo: R, P e S
Separe a Construção do Uso no Sistema 3.11 Sistemas Complexos
As demais classes não
devem conhecer sobre
contexto e inicialização
Devem ser projetadas
como se isso fosse ser
resolvido para elas…
E será!
Main conhece o sistema
Sistema ignora o Main
Função pura ignora tudo
fora do seu escopo
Injeção de Dependência Via Construtor 3.11 Sistemas Complexos
O uso de CDI com
@inject faz o mesmo
trabalho automaticamente
Injeção de dependência minimiza o
acoplamento entre classes além de
facilitar os testes de unidade
DSL – Domain Specific Language 3.11 Sistemas Complexos
DSL: Código
Expressivo
DSL encapsula a lógica
Main main()
Negocio
Módulo A
Domain Service
Módulo B
Função X1
Classe X Função X2
Função X3
Factory Create
Módulo C
Função Y1
Classe Y Função Y2
Função Y3
Repository Save
Classes e Funções são negócio destilado
O domínio do problema é descrito na solução
Parte 3.12Parte 3.12
SimplicidadeSimplicidade
Filosofia sobre Simplicidade 3.12 Simplicidade
- Todos os testes devem passar (deve haver testes)
- Nenhuma duplicação de código ou configuração
- O código deve expressar o negócio e sua intenção
- A solução deve usar o mínimo de elementos
- Simples não é Simplório (pelo contrário)
- Simplicidade é a sofisticação máxima
As 4 Regras da Simplicidade 3.12 Simplicidade
Testes Tempestivos
Refatoração Tempestiva
https://martinfowler.com/bliki/BeckDesignRules.html
Regra 1 de Projeto Simples: Efetue Todos os Testes 3.12 Simplicidade
1 2
3
Teste 1: Afere se a regra entre as opções
está funcionando: Pedra vence Tesoura,
Tesoura vence Papel e Papel vence Pedra
Teste 2: Afere se o SmartMatch retorna o
resultado certo dado que já se sabe o que
os jogadores vão escolher (mock)
Teste 3: Afere que, de 7 rodadas, irá parar
na quarta com 4 vitórias de “Bob”
Regras de 2 a 4 de Projeto Simples: Refatoração 3.12 Simplicidade
Conceitos
- O Jogo e os resultados
- Uma Disputa entre jogadores
- O resultado de uma disputa
- Jogador com nome e escolha
- A opção de jogada
DSL: Código
Expressivo
A: Reúso
B: Refactoring
Regra
1 conceito p/ classe
já sei clean code?
técnicatécnica, treino e tempo, treino e tempo
abordagem de atuação profissional
não é sobre códigonão é sobre código
é sobreé sobre fazer códigofazer código
RefatoraçãoRefatoração
Parte 4
Laboratório de Refatoração 4 Refatoração
treinotreino
github.com/refactown/lab
REFERÊNCIAS
BECK, Kent. Padrões de Implementação. Porto Alegre, Bookman, 2013.
EVANS, E. Domain-Driven Design – Atacando as complexidades no coração do software. 2a edição, Rio de
Janeiro, Alta Books, 2010.
FOWLER, Martin. BeckDesignRules, https://martinfowler.com/bliki/BeckDesignRules.html
FOWLER, Martin. TellDontAsk, https://martinfowler.com/bliki/TellDontAsk.html
HUNT, Andrew; THOMAS, David, O Programador Pragmático, Bookman, 2010
MARTIN, Robert, O Codificador Limpo, Alta Books, Rio de Janeiro 2012
MARTIN, Robert, Código Limpo, Alta Books, Rio de Janeiro 2011
Programação Funcional X Orientação a Objetos
155/155
1 42 3 5
Prática
para encerrar...
Obrigado!
Douglas Siviotti
douglas.siviotti@gmail.com
github.com/siviotti
Teoria

Mais conteúdo relacionado

Mais procurados (20)

Curso de HTML5 - Aula 01
Curso de HTML5 - Aula 01   Curso de HTML5 - Aula 01
Curso de HTML5 - Aula 01
 
Clean code
Clean codeClean code
Clean code
 
Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)
 
Padrões de Projeto de Software
Padrões de Projeto de SoftwarePadrões de Projeto de Software
Padrões de Projeto de Software
 
Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)
 
Aula 2 - Comandos DDL DML DQL E DCL
Aula 2 - Comandos DDL DML DQL E DCLAula 2 - Comandos DDL DML DQL E DCL
Aula 2 - Comandos DDL DML DQL E DCL
 
Implementing DDD with C#
Implementing DDD with C#Implementing DDD with C#
Implementing DDD with C#
 
Apostila de Fundamentos Java
Apostila de Fundamentos JavaApostila de Fundamentos Java
Apostila de Fundamentos Java
 
JAVA - Herança
JAVA - HerançaJAVA - Herança
JAVA - Herança
 
Java orientação a objetos (associacao, composicao, agregacao)
Java   orientação a objetos (associacao, composicao, agregacao)Java   orientação a objetos (associacao, composicao, agregacao)
Java orientação a objetos (associacao, composicao, agregacao)
 
Aula javascript
Aula  javascriptAula  javascript
Aula javascript
 
UML
UMLUML
UML
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
POO - Aula 09 - Herança
POO - Aula 09 - HerançaPOO - Aula 09 - Herança
POO - Aula 09 - Herança
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Princípios S.O.L.I.D.
Princípios S.O.L.I.D.Princípios S.O.L.I.D.
Princípios S.O.L.I.D.
 
Aula 09 - introducao oo
Aula 09 - introducao ooAula 09 - introducao oo
Aula 09 - introducao oo
 
Clean Code na Prática
Clean Code na PráticaClean Code na Prática
Clean Code na Prática
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
Interfaces e polimorfismo
Interfaces e polimorfismoInterfaces e polimorfismo
Interfaces e polimorfismo
 

Semelhante a clean code

Introdução ao Domain-Driven Design
Introdução ao Domain-Driven DesignIntrodução ao Domain-Driven Design
Introdução ao Domain-Driven DesignAndré Borgonovo
 
Scrum e o Ambiente de Desenvolvimento Ágil
Scrum e o Ambiente de Desenvolvimento ÁgilScrum e o Ambiente de Desenvolvimento Ágil
Scrum e o Ambiente de Desenvolvimento Ágilabacrazy
 
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
 
TDD para "meros mortais"
TDD para "meros mortais"TDD para "meros mortais"
TDD para "meros mortais"thiagobapt
 
DDD e PHP - TDC 2012
DDD e PHP - TDC 2012DDD e PHP - TDC 2012
DDD e PHP - TDC 2012Luís Cobucci
 
Programando com prazer com DDD
Programando com prazer com DDDProgramando com prazer com DDD
Programando com prazer com DDDGiovanni Bassi
 
Clean code - Qualidade em desenvolvimento de Software
Clean code - Qualidade em desenvolvimento de SoftwareClean code - Qualidade em desenvolvimento de Software
Clean code - Qualidade em desenvolvimento de SoftwareGabriel Felipe Soares
 
Domain-Driven-Design
Domain-Driven-DesignDomain-Driven-Design
Domain-Driven-DesignWende Mendes
 
Domain-Driven-Design
 Domain-Driven-Design Domain-Driven-Design
Domain-Driven-DesignWende Mendes
 
Uma introdução ao Domain Driven Design
Uma introdução ao Domain Driven DesignUma introdução ao Domain Driven Design
Uma introdução ao Domain Driven DesignLambda3
 
Mitos do Desenvolvimento de Software
Mitos do Desenvolvimento de SoftwareMitos do Desenvolvimento de Software
Mitos do Desenvolvimento de Softwareguest2f8cba
 
XP - Extreme Programming
XP - Extreme ProgrammingXP - Extreme Programming
XP - Extreme ProgrammingRodrigo Branas
 
A influência do Test-Driven Design no projeto de classes e no design em siste...
A influência do Test-Driven Design no projeto de classes e no design em siste...A influência do Test-Driven Design no projeto de classes e no design em siste...
A influência do Test-Driven Design no projeto de classes e no design em siste...Toni Esteves
 
[GDG Quality Fest 2017] BDD - Como quebrar as barreiras de negócio dentro do ...
[GDG Quality Fest 2017] BDD - Como quebrar as barreiras de negócio dentro do ...[GDG Quality Fest 2017] BDD - Como quebrar as barreiras de negócio dentro do ...
[GDG Quality Fest 2017] BDD - Como quebrar as barreiras de negócio dentro do ...Andrelise Rafael Gonçalves
 
Utilizando BDD com Specflow e Selenium para testes Web MSP Tech Day Curitiba
Utilizando BDD com Specflow e Selenium para testes Web MSP Tech Day CuritibaUtilizando BDD com Specflow e Selenium para testes Web MSP Tech Day Curitiba
Utilizando BDD com Specflow e Selenium para testes Web MSP Tech Day CuritibaCleiton Felipe Moraes
 

Semelhante a clean code (20)

Introdução ao Domain-Driven Design
Introdução ao Domain-Driven DesignIntrodução ao Domain-Driven Design
Introdução ao Domain-Driven Design
 
Scrum e o Ambiente de Desenvolvimento Ágil
Scrum e o Ambiente de Desenvolvimento ÁgilScrum e o Ambiente de Desenvolvimento Ágil
Scrum e o Ambiente de Desenvolvimento Ágil
 
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
 
TDD para "meros mortais"
TDD para "meros mortais"TDD para "meros mortais"
TDD para "meros mortais"
 
DDD e PHP - TDC 2012
DDD e PHP - TDC 2012DDD e PHP - TDC 2012
DDD e PHP - TDC 2012
 
Programando com prazer com DDD
Programando com prazer com DDDProgramando com prazer com DDD
Programando com prazer com DDD
 
Clean code - Qualidade em desenvolvimento de Software
Clean code - Qualidade em desenvolvimento de SoftwareClean code - Qualidade em desenvolvimento de Software
Clean code - Qualidade em desenvolvimento de Software
 
Domain-Driven-Design
Domain-Driven-DesignDomain-Driven-Design
Domain-Driven-Design
 
Domain-Driven-Design
 Domain-Driven-Design Domain-Driven-Design
Domain-Driven-Design
 
Uma introdução ao Domain Driven Design
Uma introdução ao Domain Driven DesignUma introdução ao Domain Driven Design
Uma introdução ao Domain Driven Design
 
Mitos do Desenvolvimento de Software
Mitos do Desenvolvimento de SoftwareMitos do Desenvolvimento de Software
Mitos do Desenvolvimento de Software
 
XP - Extreme Programming
XP - Extreme ProgrammingXP - Extreme Programming
XP - Extreme Programming
 
BDD
BDDBDD
BDD
 
Test First, TDD e outros Bichos
Test First, TDD e outros BichosTest First, TDD e outros Bichos
Test First, TDD e outros Bichos
 
Como desenvolver-software
Como desenvolver-softwareComo desenvolver-software
Como desenvolver-software
 
A influência do Test-Driven Design no projeto de classes e no design em siste...
A influência do Test-Driven Design no projeto de classes e no design em siste...A influência do Test-Driven Design no projeto de classes e no design em siste...
A influência do Test-Driven Design no projeto de classes e no design em siste...
 
Pensando TDD
Pensando TDDPensando TDD
Pensando TDD
 
[GDG Quality Fest 2017] BDD - Como quebrar as barreiras de negócio dentro do ...
[GDG Quality Fest 2017] BDD - Como quebrar as barreiras de negócio dentro do ...[GDG Quality Fest 2017] BDD - Como quebrar as barreiras de negócio dentro do ...
[GDG Quality Fest 2017] BDD - Como quebrar as barreiras de negócio dentro do ...
 
TCC - Código Limpo
TCC - Código LimpoTCC - Código Limpo
TCC - Código Limpo
 
Utilizando BDD com Specflow e Selenium para testes Web MSP Tech Day Curitiba
Utilizando BDD com Specflow e Selenium para testes Web MSP Tech Day CuritibaUtilizando BDD com Specflow e Selenium para testes Web MSP Tech Day Curitiba
Utilizando BDD com Specflow e Selenium para testes Web MSP Tech Day Curitiba
 

Mais de Douglas Siviotti

tdc-2023-bh-ciclomatica-ou-cognitiva.pdf
tdc-2023-bh-ciclomatica-ou-cognitiva.pdftdc-2023-bh-ciclomatica-ou-cognitiva.pdf
tdc-2023-bh-ciclomatica-ou-cognitiva.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 Clausula de Guarda
TDC Connections 2021 Clausula de GuardaTDC Connections 2021 Clausula de Guarda
TDC Connections 2021 Clausula de GuardaDouglas 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-complexidade-cognitiva
tdc-recife-2020-complexidade-cognitivatdc-recife-2020-complexidade-cognitiva
tdc-recife-2020-complexidade-cognitivaDouglas 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 (19)

tdc-2023-bh-ciclomatica-ou-cognitiva.pdf
tdc-2023-bh-ciclomatica-ou-cognitiva.pdftdc-2023-bh-ciclomatica-ou-cognitiva.pdf
tdc-2023-bh-ciclomatica-ou-cognitiva.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 Clausula de Guarda
TDC Connections 2021 Clausula de GuardaTDC Connections 2021 Clausula de Guarda
TDC Connections 2021 Clausula de Guarda
 
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-complexidade-cognitiva
tdc-recife-2020-complexidade-cognitivatdc-recife-2020-complexidade-cognitiva
tdc-recife-2020-complexidade-cognitiva
 
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
 
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
 
Complexidade Cognitiva
Complexidade CognitivaComplexidade Cognitiva
Complexidade Cognitiva
 
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
Complexidade CiclomáticaComplexidade Ciclomática
Complexidade Ciclomática
 

clean code

  • 1. Clean Code na Prática Conceitos de Clean Code Apresentados em Exemplos de Código Douglas Siviotti Novembro de 2019 V1.1
  • 2. Sobre esta Apresentação 1. Conteúdo: Clean Code (Código Limpo) 2. Área/Foco: Engenharia de Software, Desenvolvimento Ágil 3. Público alvo: Desenvolvedores 4. Conteúdo relacionado: OO, Programação Funcional, DDD, SOLID, GRASP Organização (155 slides) Parte 1 – Um Pouco de Filosofia Parte 2 – Um Pouco de Teoria (Conceitos Relacionados) Parte 3 – Clean Code na Prática em Exemplos de Código Parte 4 – Laboratório de Refatoração Código-fonte usado nesta apresentação: https://github.com/refactown/cleancode Cognição Micro Design Integração Macro Design
  • 3. Sintomas comuns equipe entregando cada vez menos pontos a cada sprint estimativas frustradas: o esforço é sempre maior que o previsto erros frequentes em produção correção de um bug causa outros problemas não previstos incidentes resolvidos e o mesmo erro voltando a aparecer muito “To Do” espalhado pelo código e/ou código morto dificuldade de evolução ou incorporação de novas funcionalidades
  • 4. Código Ruim manutenção difícil + retrabalho e - produtividade Código Ruim manutenção difícil + retrabalho e - produtividade Procrastinação aversão a mudanças criação de dívida técnica Procrastinação aversão a mudanças criação de dívida técnica Falta de Testes design pobre e inflexível falta de segurança p/ o dev Falta de Testes design pobre e inflexível falta de segurança p/ o dev Pressão bugs, incidentes, pouco valor, baixa evolução: insatisfação Pressão bugs, incidentes, pouco valor, baixa evolução: insatisfação ciclo vicioso da dívida técnica
  • 5. Código Limpo fácil de entender e manter expressa o negócio Código Limpo fácil de entender e manter expressa o negócio Refatoração adaptação ao novo problema tratamento de dívida técnica Refatoração adaptação ao novo problema tratamento de dívida técnica Teste de Unidade guiando o design (feedback) com boa cobertura Teste de Unidade guiando o design (feedback) com boa cobertura Entregas c/ Valor evolução sustentável cliente satisfeito Entregas c/ Valor evolução sustentável cliente satisfeito ciclo da eficácia no software sob medida
  • 6. Clean Code Fazer código para ser lido e entendido por outras pessoas Clean Code Fazer código para ser lido e entendido por outras pessoas Refatoração adaptação ao novo problema tratamento de dívida técnica Teste de Unidade guiando o design (feedback) com boa cobertura Entregas c/ Valor evolução sustentável cliente satisfeito ciclo da eficácia no software sob medida
  • 7. Um PoucoUm Pouco de Filosofiade Filosofia Parte 1
  • 8. Pequenas CoisasPequenas Coisas ImportamImportam “Deus está nos detalhes” “Menos é mais” (Ludwig Mies van der Rohe) Quem não faz bem as pequenas coisas, não faz bem coisa alguma
  • 9. código é detalhamentocódigo é detalhamento dos requisitos e devedos requisitos e deve expressar o negócioexpressar o negócio
  • 10. código deve ser feito para ser lido por outra pessoacódigo deve ser feito para ser lido por outra pessoa comunique, não codifique!
  • 11. código ruim geracódigo ruim gera baixa produtividadebaixa produtividade que gera código piorque gera código pior seja um glóbulo branco prevenir é melhor que remediar por que
  • 12. CódigoCódigo Limpo?Limpo? “elegante e eficiente faz apenas uma coisa” Bjarne Stroustrup “simples e direto - legível” Grady Booch “inteligível ao seres humanos” Dave Thomas “escrito por alguém que se importava” Michael Feathers “sem duplicação, expressivo, pequenas abstrações” Ron Jeffries “a linguagem parece que foi feita para o problema” Ward Cunningham O que é
  • 13. A T I T U D EA T I T U D E teoria da janela quebrada regra do escoteiro quando programador profissional quem quando
  • 14. técnica, treino e tempotécnica, treino e tempo livros de arte não fazem um artista trabalho artesanal mas profissional como
  • 15. Um Pouco de Teoria*Um Pouco de Teoria* *Oriunda de muita prática*Oriunda de muita prática Parte 2
  • 16. Título do Slide (Arial 18) 16/155 2.1 DDD: Negócio ao Código 2.2 Linguagem Onipresente 2.3 Princípio SRP 2.4 Princípio DRY 2.5 Indireção / Delegação 2.6 Lei de Demeter 2.7 Acoplamento e Coesão 2.8 Imutabilidade 2.9 OO + Funções Puras 2.10 Testes Tempestivos 2.11 Refatoração Tempestiva 2.12 Regras da Simplicidade Conceitos relacionados
  • 17. O requisito está no código, mas muito código não vem do requisito O domínio de um problema organiza os conceitos sobre os quais é baseada a solução de software Foco no Negócio Parte do código deve expressar o negócio Isolamento do Domínio O código de domínio é idiossincrático e particular Infraestrutura à Parte Tecnologias vêm e vão, o negócio permanece Do Negócio ao Código Via DDD 2.1 Negócio ao Código Domain
  • 18. DDD e os Nomes das Coisas 2.2 Linguagem Onipresente Ubiquos Language Service Entity Value Object Agregate Factory Model-driven Design Bounded Context RepositoryDomain Events Layered Architecture Core Domain Context Map Continuos Integration Linguagem Onipresente (Ubíqua) - Termos e conceitos usados pelos desenvolvedores e pelos especialistas no negócio - Presente na fala de todos e no código de domínio Contexto Delimitado - Partes bem delimitadas de um domínio - Candidatos a microsserviços Tijolos de Construção - Entidades, Objetos de Valor, Agregados - Eventos de Domínio - Serviços, Fábricas, Repositórios
  • 19. Princípio da Responsabilidade Única (SRP) 2.3 Princípio SRP “Cada módulo de um software deve ter um e apenas um motivo para mudar” 1 O que seria apenas “uma” responsabilidade?
  • 20. Menos é Mais 2.4 Princípio DRY DRY = Don’t Repeat Yourself “Não Se Repita” (código, requisito, teste etc) Toda parte do conhecimento deve ter uma representação única e livre de ambiguidades em todo o sistema Problemas - Mais trabalho: alterar mais vezes - Mais risco: encontrar todos os lugares - Mais teste: testar várias vezes a mesma coisa - Mais esforço de comunicação
  • 21. Indireção ou Delegação 2.5 Indireção / Delegação SRP Fazer apenas uma coisa em um certo lugar SRP Fazer apenas uma coisa em um certo lugar DRY Fazer apenas em um lugar uma certa coisa DRY Fazer apenas em um lugar uma certa coisa Coisa única em um único lugar “A” Coisa única em um único lugar “A” Outra coisa única em um único lugar “B” Outra coisa única em um único lugar “B” Indireção ou Delegação 1. Não pode conter 2. Não pode copiar 3. Precisa referenciar Indireção Indireção Calculo de Frete Busca de EndereçoEfetuar Pedido
  • 22. Lei de Demeter – Princípio do Menor Conhecimento 2.6 Lei de Demeter Um módulo não deve enxergar o interior dos objetos que ele manipula Um método “m” de uma classe “C” só deve chamar: - Objetos do tipo “C” - Parâmetros passados para o método “m” (e.g. “x: P”) - Um objeto criado pelo próprio método “m” - Variáveis de instância da classe “C” (e.g. “a: A”) Train Wreck (Acidente de Trem): x.getY().getZ() “Você não manda as pernas do cachorro andarem e sim o cachorro” Classe “C” Atributo a: A Método “m” (x: X) Classe X Atributo y : Y Classe Y Atributo z : Z
  • 23. Baixo Acoplamento e Alta Coesão 2.7 Acoplamento e Coesão Alto Acoplamento Baixa Coesão (entre classes) Poucas classes e grandes Mais dependência por classe Maior conhecimento Baixo Acoplamento Alta Coesão (entre classes) Muitas classes e pequenas Menos dependência por classe Menor conhecimento Coesão de uma Classe: - Poucas variáveis de instância - Cada método manipula uma ou mais Uma classe pouco coesa sugere que uma nova classe deve “nascer”
  • 24. Quanto Mais Imutável Melhor 2.8 Imutabilidade Evite Surpresas Imutabilidade é uma defesa contra efeitos colaterais Vantagens - Mais seguro e confiável - Mais legível: minimiza testes e garantias diminui o código por tabela - Paralelismo e escalabilidade private final int idade;
  • 25. Quanto Mais Puro Melhor 2.9 OO + Funções Puras Função Pura 1. Para um certo Input sempre retorna o mesmo Output 2. Não causa nenhum efeito colateral 3. Não depende de nenhum dado externo (autocontida) Vantagens - Mais simples e menores - Mais fácil de entender e testar Quando usar em código OO? Sempre que possível Em muitas situações não é possível: BD, integração, estados etc Possível em regras de negócio, métodos utilitários, internos etc Function Input Output IMUTABILIDADE - efeitos colaterais
  • 26. TDD e Testes Tempestivos 2.10 Testes Tempestivos TDD – Test Driven Development (Desenvolvimento Guiado por Testes) - Escreve um teste que falha antes do código produtivo - Faz o teste passar ao construir o código produtivo - Refatora o código até o teste falhar (ou não) Testes Tempestivos (TDD inclusive) (teste que ajuda na construção, logo cedo) 1. Atividade de engenharia (código e design) 2. Feedback rápido sobre o código testado (erra cedo) 3. Gera código limpo através da “dificuldade” de testar 4. Antecipa o custo gasto em correções e debug 5. Ainda serve como teste de regressão Refatora Falha Passa Ciclos Curtos
  • 27. Refatoração Tempestiva 2.11 Refatoração “Refatoração (refactoring) é a disciplina técnica para reestruturar um determinado código, alterando sua estrutura interna sem mudar seu comportamento externo” Martin Fowler Problema Inicial Solução Inicial Problema Refinado Refatoração Mudança Solução Final Validar Solução Refinamento Ciclo de Sprint Ajuste da solução em função de: - uma nova visão sobre o problema - preparar para uma evolução ou mudança Pequenas mudanças que fazem diferença no longo prazo
  • 28. Quatro Regras da Simplicidade (Martin Fowler : Kent Beck) 2.12 Simplicidade Testes Tempestivos Refatoração Tempestiva https://martinfowler.com/bliki/BeckDesignRules.html
  • 29. Conceitos Relacionados Conceitos DDDDDD Linguagem Onipresente Linguagem Onipresente Indireção Abstração, especialização Indireção Abstração, especialização Lei de Demeter Mínimo conhecimento Lei de Demeter Mínimo conhecimento Princípio SRP Responsabilidade Única Princípio SRP Responsabilidade Única Princípio DRY Não Se Repita Princípio DRY Não Se Repita Acoplamento e Coesão Acoplamento e Coesão Funções Puras OO ou funcional Funções Puras OO ou funcionalInfraInfra DomínioDomínio AppApp Refatoração Tempestiva Refatoração Tempestiva Teste Tempestivo Teste Tempestivo 4 Regras da Simplicidade 4 Regras da Simplicidade Imutabilidade - efeitos colaterais Imutabilidade - efeitos colaterais Clean Code Clean Code
  • 31. Título do Slide (Arial 18) 31/155 3.1 Código Limpo 3.2 Nomes Significativos 3.3 Comentários (capítulo 4) 3.4 Formatação (capítulo 5) 3.5 Funções (capítulo 3) 3.6 Objetos e E. de Dados 3.7 Tratamento de Erro 3.8 Fronteiras (Limites) 3.9 Testes de Unidade 3.10 Classes 3.11 Sistemas Complexos 3.12 Simplicidade Prática - filosofia - bad smell - boa prática - exemplo - exercício Cognição Entendimento e leitura Integração Contratos e expectativas Macro Design Escala e expansão Micro Design Estado e comportamento
  • 32. Código LimpoCódigo Limpo (Visão Geral)(Visão Geral) Parte 3.1Parte 3.1
  • 33. Filosofia sobre Código Limpo (Visão Geral) 3.1 Código Limpo - O código não fica nem se mantém limpo sozinho - Todos na equipe devem praticar e cobrar - Manter o código limpo é uma atividade diária - Funciona como na “Teoria das janelas quebradas” - Atitude é mais relevante do que “patrocínio” - Sempre dá pra começar (regra do escoteiro) - Ler e entender consome mais tempo que escrever - Precisa de tempo, técnica e treino pra fazer bem
  • 34. Código Ruim 3.1 Código Limpo Problemas - Nomes ruins - Função grande e complexa (SRP) - Comentários questionáveis - Formatação inexistente Dificuldades - Legibilidade: confuso - Testabilidade: alta complexidade
  • 35. Código Menos Ruim 3.1 Código Limpo Problemas - Nomes ruins - Função grande e complexa (SRP) - Comentários questionáveis - Formatação inexistente Dificuldades - Legibilidade: confuso - Testabilidade: alta complexidade
  • 36. Código Melhorado (Refatorado) 3.1 Código Limpo O que pode melhorar?
  • 37. Possíveis Melhorias 3.1 Código Limpo Lançar Exceção Constantes Enum “Premio” Classe Separada
  • 39. Filosofia sobre Nomes 3.2 Nomes Significativos - Nomes são muito importantes (especialmente em OO) - Use nomes que revelam seu propósito - Evite informações erradas (itemList: Map) - Faça distinções significativas (evite a1, a2 a3...) - Nomes pronunciáveis e passíveis de busca - Evite codificações (e.g. notação húngara e similares) - classes = substantivos, métodos = verbos - Selecione uma palavra por conceito (get, set, find) - Nomes do problema (Pedido, Item) e da solução (DAO) - Adicione ou evite contexto quando necessário
  • 40. Bad Smell 3.2 Nomes Significativos Problemas - Nomes genéricos “i”, “x”, “d” etc - Nomes impronunciáveis - Número Mágico (perdido no código) - Notação Húngara - Interface prefixada - Nome com contexto redundante
  • 41. Boa Prática 3.2 Nomes Significativos Alternativas - Nomes que revelam propósito - Nomes pronunciáveis - Constantes para número mágico (passíveis de busca) - Sem Notação Húngara - Interface = Conceito - Nomes com o mínimo necessário
  • 42. Problema x Solução 3.2 Nomes Significativos Problema Solução
  • 43. Modelo de Exemplo 3.2 Nomes Significativos Nomes a partir do domínio do problema (Pedido, Item etc) Nomes a partir do domínio da solução (Controller, Delegate, DAO) Classes = Substantivos, Métodos = Verbos Nomes pronunciáveis e passíveis de busca
  • 45. Filosofia sobre Comentários 3.3 Comentários “Qualquer um pode escrever código que o computador entenda. Bons programadores escrevem códigos que os humanos entendem.” Martin Fowler - Comentários são a última opção do programador - O programador deve expressar-se no código - Comunique, não codifique (outros devem ler) - Comentário pode estar compensando código ruim - Alguns comentários são bons ou necessários
  • 46. Explique-se no Código 3.3 Comentários Alguns comentários existem para explicar código ruim. Um comentário deve explicar “o porquê” e nunca “o que” Não comente, refatore!
  • 47. Comentários Bons: Legais e APIs Públicas 3.3 Comentários
  • 48. Comentários Bons: Alguns “TODO”, Alertas e Destaques 3.3 Comentários
  • 49. Comentário Ruim: Murmúrio e Redundância 3.3 Comentários
  • 50. Comentário Ruim: Código Morto e/ou com Autoria 3.3 Comentários Use o controle de versão!
  • 51. Outros Comentários Ruins 3.3 Comentários - Ruidosos, muito longos ou repetitivos - Imperativos (e.g. em todas as funções) - Marcadores de Posição //////////////// ou ************ - Ao lado de chaves de fechamento (e.g. //for) - Comentários em HTML - Informações excessivas - Conexões nada óbvias - Cabeçalhos de funções (prefira um bom nome) - Javadoc em código não público
  • 53. Filosofia sobre Formatação 3.4 Formatação - Atenção ao “code convention” da linguagem - O projeto deve ter um “code style” (bom ou ruim) - Qualquer “code style” é melhor que nenhum - A formatação automática evita muitas brigas - Formatação vertical Metáfora do jornal, distância vertical, espaçamento e continuidade vertical - Formatação horizontal Indentação, espaçamento e continuidade horizontal
  • 54. Formatação Vertical: Metáfora do Jornal 3.4 Formatação
  • 55. Formatação Vertical: Continuidade e Espaçamento Vertical 3.4 Formatação Linhas de código relacionadas devem permanecer unidas Pensamentos completos devem ser separados por espaços em branco
  • 56. Formatação Vertical: Distância Vertical 3.4 Formatação Declaração de Variável O mais próximo possível de onde será usada Variáveis de Instância Antes dos métodos Funções Dependentes Verticalmente próximas Afinidade Conceitual Mesma convenção de nomes atuam na mesma tarefa devem ficar próximas
  • 57. Formatação Horizontal 3.4 Formatação Evite - Espaçamentos manuais - Indentação do “seu gosto” - Mais de 120 caracteres por linha Deixe a IDE trabalhar - Espaçamentos automáticos - Indentação padrão - Quebras de linha
  • 58. Regra da Tela 3.4 Formatação <= 20 Cabe na tela <= 500 100-120 Cabe na tela
  • 59. Code Convention + Regra da Equipe 3.4 Formatação Mantenha a paz no seu projeto: tenha um “code style” combinado pela equipe
  • 61. Filosofia sobre Funções 3.5 Funções - Funções devem ser pequenas (<= 20 linhas) - Funções devem fazer apenas uma coisa - Devem ter nomes descritivos do que fazem - Somente um nível de abstração por função - Funções devem ter poucos parâmetros - Efeitos colaterais devem ser evitados ao máximo - Quanto mais funções puras, melhor - Quanto mais autocontida mais fácil de testar
  • 62. Clean Code (2008) Programação Funcional (1958) Pura Sem efeitos colaterais 1 nível de abstração Faz apenas 1 coisa Pequena Clean Code + Programação Funcional 3.5 Funções
  • 63. Regra 1 3.5 Funções Faz Apenas 1 Coisa - Nomes, comentários e formatação são importantes para a leitura, mas as funções são o que o programa realmente faz - É melhor ler e entender uma coisa de cada vez - É melhor testar uma coisa de cada vez 1 Nível de Abstração - Cada conceito em seu lugar apropriado Abstração é a capacidade de separar o essencial do que não é essencial. Separar conceitos dos detalhes.
  • 64. 3.5 FunçõesExemplo de Função “Suja” Grande (34 linhas) Faz muitas coisas: 1. Valida os números apostados 2. Verifica se está entre 6 e 15 3. Sorteia 6 números 4. Conta os acertos 5. Calcula o prêmio Vários níveis de abstração 1 2 3 4 5
  • 65. Exemplo de Função “Limpa” 3.5 Funções Pequena (11 linhas) Faz 1 coisa: 1. Valida os números apostados 2. Verifica se está entre 6 e 15 3. Sorteia 6 números 4. Conta os acertos 5. Calcula o prêmio 1 nível de abstração 1 coisa e 1 nível de abstração Indireção
  • 66. Regra Decrescente 3.5 Funções Indireção Nível de abstração 1 Nível de abstração 2 Leitura de cima para baixo Nomes descritivos do que fazem
  • 67. Switch Highlander (Java) 3.5 Funções Um “Switch” deve estar em uma classe de nível mais baixo de abstração e nunca ser repetido Opção procedural Opção polimórfica
  • 68. Switch Highlander (Kotlin) 3.5 Funções Um “Switch” deve estar em uma classe de nível mais baixo de abstração e nunca ser repetido Opção procedural Opção polimórfica
  • 69. Fibonacci (Funções Puras) 3.5 Funções 1. Para um certo Input sempre retorna o mesmo Output 2. Não causa nenhum efeito colateral 3. Não depende de nenhum dado externo (escopo)
  • 70. Pedra, Papel e Tesoura: Especificação via Teste de Unidade 3.5 Funções R (Rock/Pedra) vence S (Scissors/Tesoura) S (Scissors/Tesoura) vence P (Paper/Papel) P (Paper/Papel) vence R (Rock/Pedra)
  • 71. Pedra, Papel e Tesoura: Contrato 3.5 Funções Cabeçalho da Função: pedraPapelTesoura(char,char):int Contrato da Função: - Recebe dois caracteres (R, P ou S) - Se empata retorna 0 - Se o primeiro ganha retorna -1 - Se o segundo ganha retorna 1 - Se um dos caracteres é inválido gera uma exceção “IllegalArgumentException” (melhor que código de erro) - R vence S, S vence P, P vence R
  • 72. Pedra, Papel e Tesoura (Kotlin) 3.5 Funções 1 Nível de abstração Faz apenas 1 coisa Prefira exceções a retorno de códigos de erro! É uma função pura?
  • 73. Pedra, Papel e Tesoura (Java) 3.5 Funções É uma função pura?
  • 74. Parâmetros 3.5 Funções Função Mônade P1 Função Díade Função Tríade P1 P2 P3 P1 P2 A quantidade de parâmetros deve ser a menor possível. Se a quantidade de parâmetros é muito grande, pode ser usado um objeto como parâmetro. Objeto como Parâmetro O parâmetro tem suas regras e seus próprios conceitos
  • 75. Parâmetros Seletores e de “Saída” 3.5 Funções Parâmetro de “Saída” Saída deve ser no retorno Parâmetro Seletor É preferível dividir em duas funções Um parâmetro seletor já indica logo na assinatura que uma função faz duas coisas. O ideal é fazer duas funções separadas.
  • 76. Separação Comando-Consulta 3.5 Funções Comando + Consulta Apenas Consulta Apenas Comando As funções devem somente fazer ou responder algo, mas não ambos. Ou altera o estado de um objeto ou retorna informação sobre ele.
  • 77. Tratamento de Erro é 1 Coisa Só 3.5 Funções O “try” deve ser a primeira linha da função e não deve haver nada depois fim do bloco “try/catch/finally”
  • 78. O Cerne de Boas Funções 3.5 Funções Evite Repetição (DRY) - Indireção, extração etc podem gerar duplicação - Funções menores e especializadas requerem reúso (SRP) Faça e Refaça com Confiança - Comece fazendo funcionar e depois refatore - Tenha cobertura de testes para ter confiança Funções são verbos do domínio - Uma hierarquia de funções conta uma estória - Níveis de abstração ajudam na leitura da estória
  • 79. Objetos e EstruturasObjetos e Estruturas de Dadosde Dados Parte 3.6Parte 3.6
  • 80. Filosofia sobre Objetos e Estruturas de Dados 3.6 Objetos e E. de Dados Os objetos usam abstrações para esconder seus dados e expõem funções que operam sobre eles Estruturas de dados expõem seus dados e não possuem funções significativas (get/set = acessores) - Objetos buscam o menor conhecimento - Estruturas de dados (DTO) buscam imutabilidade
  • 81. Estruturas de Dados nas Linguagens 3.6 Objetos e E. de Dados Kotlin tem uma palavra reservada para definir uma estrutura de dados: “data”. A sintaxe deixa clara a diferença entre uma estrutura de dados e demais classes/objetos
  • 82. PedidoDTO 3.6 Objetos e E. de Dados Objeto ou Estrutura de Dados?
  • 83. Pedido 3.6 Objetos e E. de Dados Objeto ou Estrutura de Dados?
  • 84. Pedido Com Mais Encapsulamento 3.6 Objetos e E. de Dados Objeto ou Estrutura de Dados?
  • 85. Feature Envy (Inveja de Funcionalidade) 3.6 Objetos e E. de Dados https://martinfowler.com/bliki/TellDontAsk.html Um objeto tem “inveja” da funcionalidade de que deveria ser implementada em outro objeto No exemplo abaixo, o primeiro “IF” tem inveja da funcionalidade que diz se um pedido é válido, mas pedido é um OBJETO Numa ESTRUTURA DE DADOS isso não seria problema Princípio “Tell Don’t Ask” Indireção Sobre uma Estrutura de Dados Sobre um Objeto
  • 86. Procedural x Orientado a Objetos (OO) 3.6 Objetos e E. de Dados E se precisar calcular o perímetro? (as estruturas de dados não serão afetadas) E se precisar criar a classe triângulo?
  • 87. Espectros de Objetos / Estrutura de Dados 3.6 Objetos e E. de Dados Encapsulamento Estrutura de Dados ObjetosHíbridos Imutabilidade Facilita a adição de novas funcionalidades Facilita a adição de novas classes Triângulo Perímetro
  • 88. Feature Envy no Modelo de Figuras (Shape) 3.6 Objetos e E. de Dados
  • 89. Feature Envy + Efeitos Colaterais 3.6 Objetos e E. de Dados
  • 90. Lei de Demeter sobre Objetos 3.6 Objetos e E. de Dados x = a.getB().getC().getD()x = a.b.c.d Train Wrecks (Acidente de Trem) a b c d NullPointer Exception (null) Estrutura de Dados Objetos - Imutabilidade - Proibição de “null” - Estados mutáveis - Possibilidade de “null” x = a?.b?.c?.d (Navegação Segura)
  • 91. Parte 3.7Parte 3.7 Tratamento de ErroTratamento de Erro
  • 92. Filosofia sobre Tratamento de Erro 3.7 Tratamento de Erros - Use exceções em vez de retornar códigos - Prefira exceções não verificadas (unchecked) - Forneça exceções com contexto e sem abafamento - Pense no design do “try-catch-finally” antes - Defina exceções pensando no chamador (e.g. Libs) - Cada “catch” faz apenas uma coisa - Não retorne nem passe “null” - Dê preferência às exceções já fornecidas (efective java)
  • 93. Código de Exceção Ruim 3.7 Tratamento de Erros Problemas - Não retorna uma exceção - Abafa exceção do Gson - Retorna “null” - Imprime direto no console Consequências - Contrato baseado em “null” - Omissão do erro raiz (causa) - Força a testar nulidade: kotlin: ?. java: if (result != null) - Log inadequado e ineficiente
  • 94. Código de Exceção com Perda da Causa Raiz 3.7 Tratamento de Erros Problemas - Não retorna uma exceção - Abafa exceção do Gson - Retorna “null” - Imprime direto no console Consequências - Contrato baseado em “null” - Omissão do erro raiz (causa) - Força a testar nulidade: kotlin: ?. java: if (result != null) - Log inadequado e ineficiente
  • 95. Código Melhorado (Repassando a Causa Raiz) 3.7 Tratamento de Erros O que acontece se “json” ou “clazz” forem nulos? Por que nunca se deve passar “null” como parâmetro?
  • 96. Código de Teste Obtendo a Causa Raiz (Gson) 3.7 Tratamento de Erros
  • 97. Questão Sobre a Criação de Classes de Exceção 3.7 Tratamento de Erros Existe realmente a necessidade de criar a exceção “JsonException”? Não seria melhor usar as exceções prontas do Gson?
  • 99. Filosofia sobre Fronteiras 3.8 Fronteiras - Código de terceiro quase sempre é “infraestrutura” - Infraestrutura deve ser isolada do negócio - Testes de aprendizado são uma boa dica
  • 100. Estudo de Caso do Parsing de Json 3.8 Fronteiras Necessidade Fazer parsing e serialização de Json em várias partes da aplicação Inicialmente usando o “Gson” Opcionalmente pode ser usado outra biblioteca como “Jackson” A infraestrutura deve ser isolada Domain ControllerController JsonParser Interface toJson() fromJson() JsonParser Interface toJson() fromJson() GsonParserGsonParser JacksonParserJacksonParser
  • 101. Estudo de Caso do Parsing de Json 3.8 Fronteiras Terceiros Infraestrutura Infraestrutura Aplicação API de Terceiros
  • 102. Estudo de Caso do Parsing de Json 3.8 Fronteiras GsonParserGsonParser JacksonParserJacksonParser
  • 103. Parser Baseado no Gson 3.8 Fronteiras GsonParserGsonParser Encapsula o Gson É um JsonParser
  • 104. Injetando Dependência 3.8 Fronteiras Criação manual Injeção de dependência Controller Parser Interface toJson() fromJson() GsonParser JacksonParser
  • 105. Teste de Aprendizado do Gson 3.8 Fronteiras
  • 106. Parte 3.9Parte 3.9 Testes de UnidadeTestes de Unidade
  • 107. Filosofia sobre Testes de Unidade 3.9 Testes de Unidade - Teste de unidade dá feedback sobre o design - O feedback deve chegar o quanto antes - TDD é uma boa opção para tornar mais fácil - Testes de unidade são atividade de construção - Cobertura de testes provê confiança - Refatoração sem cobertura pode ser uma aventura - Teste também é código e deve ser limpo
  • 108. Cenário de Construção com TDD em 3 Iterações 3.9 Testes de Unidade Requisitos do Contador de Constantes 1. Criar uma função que conte todas as constantes inteiras de uma classe passada como parâmetro (atributos estáticos e “final”) 2. Parâmetro “null”, classes abstratas e enuns são ignorados e deve ser retornado “-1” como resultado da função 3. A contagem deve incluir todas as superclasses
  • 109. As 3 Regras do TDD 3.9 Testes de Unidade Refatora Falha Passa 1. Você não pode escrever nenhum código até ter escrito um teste que detecte uma possível falha. 2. Você não pode escrever mais testes de unidade do que o suficiente para detectar a falha – não compilar é não ter efeito. 3. Você não pode escrever mais código do que o suficiente para passar nos testes.
  • 110. TDD – Escrever a Primeira Versão do Teste e Falhar 3.9 Testes de Unidade Falha 1. Criar uma função que conte todas as constantes inteiras de uma classe (estáticos e “final”)
  • 111. TDD – Escrever o Código Real e Passar 3.9 Testes de Unidade Passa
  • 112. TDD – Refatorar o Código Real e Passar (Apenas Melhoria) 3.9 Testes de Unidade Passa Extração da lista Extração do método
  • 113. TDD – Refatorar o Teste para o Requisito 2 (Iteração 2) 3.9 Testes de Unidade 2. Classes abstratas e enuns são ignorados (retornar -1), inclusive “null” Refatora
  • 114. TDD – Teste Refatorado Vai Falhar 3.9 Testes de Unidade Falha Falha Aqui
  • 115. TDD – Ajuste do Código para Atender o Teste (Iteração 2) 3.9 Testes de Unidade Passa Adição do requisito 2
  • 116. TDD – Refatorar o Teste para o Requisito 3 (Iteração 3) 3.9 Testes de Unidade 3. A contagem deve incluir as superclasses Refatora
  • 117. TDD – Teste Refatorado Vai Falhar (Iteração 3) 3.9 Testes de Unidade Falha Tem 2 constantes Falha Aqui
  • 118. TDD – Ajuste do Código para Atender o Teste (Iteração 3) 3.9 Testes de Unidade Passa Adição do requisito 3
  • 120. Filosofia sobre Classes 3.10 Classes - Classes devem ser pequenas - Devem ter somente uma responsabilidade (SRP) - Ter apenas um motivo para mudar - Devem ter coesão interna* * Poucas variáveis de instância * Cada método manipula uma variável ou mais - Devem encapsular seus dados ao máximo - Devem ter baixo acoplamento a outras classes
  • 121. Jogando “Pedra, Papel e Tesoura” 3.10 Classes Requisitos do Melhor de 3 (Pedra, Papel e Tesoura) 1. Criar uma simulação de dois jogadores jogando “pedra, papel e tesoura” por um número variável de rodadas (3, 5 etc). 2. O jogo deve parar se um jogador já for o vencedor antes da última rodada (cenário de vitória antecipada). 3. Ao final deve ser indicado o vencedor (ou empate) e listados os resultados de todas as rodadas.
  • 122. Código Fornecido 3.10 Classes Enum Mão: Possibilidades de escolha (Pedra, Papel ou Tesoura)
  • 123. Código Fornecido 3.10 Classes Enum Resultado: Resultado em relação ao primeiro jogador: Perde: -1 Empata: 0 Vence: 1 Abstração de pedraPapelTesoura
  • 124. Código Fornecido 3.10 Classes Enum ResultadoJogada: Resultados de um match (Primeiro Vence, Empate ou Segundo Vence)
  • 125. Implementação Procedural Simples 3.10 Classes pedraPapelTesoura(char,char):int Problemas - Um método faz tudo - Muitos conceitos juntos: “Jogador”, “Match”, “Resultados” - “Rodadas” constantes - Nomes “hard coded” - Não pára em vitória antecipada Questões Como se livrar do código legado pedraPapelTesoura ? A solução é muito procedural? Como testar isso? 2 escolhas aleatórias
  • 126. Modelo Lógico: Possível Solução OO 3.10 Classes Níveis de Abstração - O Jogo e os resultados - Uma Disputa entre jogadores - O resultado de uma disputa - Jogador com nome e escolha - A opção de jogada
  • 127. Modelo Lógico: Análise dos Conceitos do Jogo 3.10 Classes Inicialização e Contexto Conceito: 1 JogadorConceito: 1 Disputa Conceito: O Jogo em si Várias rodadas e resultado Código “Legado”: Lógica do jogo Conceito: Resultado de uma Disputa Abstração sobre -1,0,1 Opções do Jogo: R, P e S
  • 128. Implementação OO - Main 3.10 Classes Instanciação de dependências Inicialização em “jogar()” I/O = Efeito colateralI/O = Efeito colateral
  • 129. Classe MelhorDeTres 3.10 Classes Responsabilidade: representa um jogo de “Pedra, Papel e Tesoura” com a definição do número de rodadas (3 por padrão) e armazena os resultados (estado) API - Executa o jogo (play) - Retorna se tem vencedor - Retorna o vencedor (se houver) - Retorna os resultados Delega para a classe Match o conhecimento sobre a disputa entre dois jogadores e seu resultado Indireção para Jogada Requisito número 2 Dependência será resolvida via construtor
  • 130. Classe JogadaLegada (Implementa Jogada) 3.10 Classes Representa uma disputa entre dois jogadores e seu resultado (imutável) API: Executa a disputa (play) e gera um resultado Delega para os jogadores a escolha da “mão” que será jogada. Delega para a função rockPaperScissors a lógica de quem venceu a disputa com base nestas escolhas
  • 131. Classe Jogador 3.10 Classes Representa um jogador que deve fazer uma escolha de qual mão usar na disputa Delega para Mao a escolha de forma aleatória, mas encapsula esta decisão O jogador poderia ser criado com a escolha já feita anteriormente
  • 132. Solução OO x Procedural 3.10 Classes A solução OO tem mais código, mas cada parte é mais fácil de entender que o todo Permite testes de unidade por classe Cada abstração está em uma classe Cada classe tem uma responsabilidade A necessidade de manutenção tende a impactar somente uma parte do código
  • 133. Refatoração: Livrando-se do Código Legado 3.10 Classes Como remover pedraPapelTesoura? Qual classe deve conhecer esta regra de quem vence quem? Como implementar a regra de forma a gerar o menor impacto possível? Qual seria o impacto de alterar e testar na solução procedural?
  • 134. Especificação da Regra “Pedra/Papel/Tesoura” Legada 3.10 Classes
  • 135. Especificação da Regra “Pedra/Papel/Tesoura” OO 3.10 Classes
  • 136. Responsabilidade da Classe “Mao” 3.10 Classes Código expressivo sobre a regra do jogo Função (API) que externaliza a regra
  • 137. Impacto: Nova Classe Implementando “Jogada” 3.10 Classes Implementação alternativa de “Jogada” livre do código legado O método “jogar” expressa o negócio de forma simples e elegante Função (API) que externaliza a regra
  • 138. JogadaLegada x JogadaSimples (Nova) 3.10 Classes - Mais semântico e claro - Dispensa o enum “Resultado” - Delega para o método “vence” de uma outra classe (“Mao”) Kotlin infix
  • 139. Impacto da Refatoração na Classe “Main” 3.10 Classes Criação da classe “JogadaSimples” (Troca de “JogadaLegada” por “JogadaSimples”) A classe “MelhorDeTres” não teve nenhum impacto e ainda recebe a dependência Responsabilidades: - Criar Jogadores - Criar Jogada - Inicializar o Jogo ... - Conexão de Banco ? - I/O, Integrações ?
  • 141. Filosofia sobre Testes de Unidade 3.11 Sistemas Complexos - Sistemas precisam de separação de preocupações - Separe a inicialização do uso de um sistema - Sistemas beneficiam-se do uso de uma DSL
  • 142. Modularização e Separação de Preocupações 3.11 Sistemas Complexos - Criação de objetos e escopos superiores - Conexão com BD, I/O e efeitos colaterais DDD e Preocupações Transversais Main main() Negocio Módulo A Domain Service Módulo B Função X1 Classe X Função X2 Função X3 Factory Create Módulo C Função Y1 Classe Y Função Y2 Função Y3 Repository Save Log Segurança BD I/O
  • 143. Inicialização e Contexto Conceito: 1 JogadorConceito: 1 Disputa Conceito: O Jogo em si Várias rodadas e resultado Código “Legado”: Lógica do jogo Conceito: Resultado de uma Disputa Abstração sobre -1,0,1 Opções do Jogo: R, P e S Separe a Construção do Uso no Sistema 3.11 Sistemas Complexos As demais classes não devem conhecer sobre contexto e inicialização Devem ser projetadas como se isso fosse ser resolvido para elas… E será! Main conhece o sistema Sistema ignora o Main Função pura ignora tudo fora do seu escopo
  • 144. Injeção de Dependência Via Construtor 3.11 Sistemas Complexos O uso de CDI com @inject faz o mesmo trabalho automaticamente Injeção de dependência minimiza o acoplamento entre classes além de facilitar os testes de unidade
  • 145. DSL – Domain Specific Language 3.11 Sistemas Complexos DSL: Código Expressivo DSL encapsula a lógica Main main() Negocio Módulo A Domain Service Módulo B Função X1 Classe X Função X2 Função X3 Factory Create Módulo C Função Y1 Classe Y Função Y2 Função Y3 Repository Save Classes e Funções são negócio destilado O domínio do problema é descrito na solução
  • 147. Filosofia sobre Simplicidade 3.12 Simplicidade - Todos os testes devem passar (deve haver testes) - Nenhuma duplicação de código ou configuração - O código deve expressar o negócio e sua intenção - A solução deve usar o mínimo de elementos - Simples não é Simplório (pelo contrário) - Simplicidade é a sofisticação máxima
  • 148. As 4 Regras da Simplicidade 3.12 Simplicidade Testes Tempestivos Refatoração Tempestiva https://martinfowler.com/bliki/BeckDesignRules.html
  • 149. Regra 1 de Projeto Simples: Efetue Todos os Testes 3.12 Simplicidade 1 2 3 Teste 1: Afere se a regra entre as opções está funcionando: Pedra vence Tesoura, Tesoura vence Papel e Papel vence Pedra Teste 2: Afere se o SmartMatch retorna o resultado certo dado que já se sabe o que os jogadores vão escolher (mock) Teste 3: Afere que, de 7 rodadas, irá parar na quarta com 4 vitórias de “Bob”
  • 150. Regras de 2 a 4 de Projeto Simples: Refatoração 3.12 Simplicidade Conceitos - O Jogo e os resultados - Uma Disputa entre jogadores - O resultado de uma disputa - Jogador com nome e escolha - A opção de jogada DSL: Código Expressivo A: Reúso B: Refactoring Regra 1 conceito p/ classe
  • 151. já sei clean code? técnicatécnica, treino e tempo, treino e tempo abordagem de atuação profissional não é sobre códigonão é sobre código é sobreé sobre fazer códigofazer código
  • 153. Laboratório de Refatoração 4 Refatoração treinotreino github.com/refactown/lab
  • 154. REFERÊNCIAS BECK, Kent. Padrões de Implementação. Porto Alegre, Bookman, 2013. EVANS, E. Domain-Driven Design – Atacando as complexidades no coração do software. 2a edição, Rio de Janeiro, Alta Books, 2010. FOWLER, Martin. BeckDesignRules, https://martinfowler.com/bliki/BeckDesignRules.html FOWLER, Martin. TellDontAsk, https://martinfowler.com/bliki/TellDontAsk.html HUNT, Andrew; THOMAS, David, O Programador Pragmático, Bookman, 2010 MARTIN, Robert, O Codificador Limpo, Alta Books, Rio de Janeiro 2012 MARTIN, Robert, Código Limpo, Alta Books, Rio de Janeiro 2011
  • 155. Programação Funcional X Orientação a Objetos 155/155 1 42 3 5 Prática para encerrar... Obrigado! Douglas Siviotti douglas.siviotti@gmail.com github.com/siviotti Teoria