Refatorando tudo! [Agile brazil 2017]
-
Upload
marcos-brizeno -
Category
Technology
-
view
106 -
download
0
Transcript of Refatorando tudo! [Agile brazil 2017]
Refatorando TUDO!
@marcosbrizeno
@marcosbrizeno
A única maneirade ir rápidoé ter qualidade
https://pt.wikipedia.org/wiki/Procrastinação
tempo
esforço
prazo
tempo
esforço
tempo
esforço
O Scrum resolve esse problema!
tempo
esforço
...
Iteração 1 Iteração 2 Iteração n...
...
tempo
esforço
You can't ship process
A única maneirade ir rápidoé ter qualidade
https://www.youtube.com/watch?v=hG4LH6P8Syk
Mão na massa: Renomear um método
Mão na massa: Renomear um método
Renomear um método é simples!
Renomear um método é simples!
- Muda o nome do método
Renomear um método é simples!
- Muda o nome do método
- Procura onde é chamado e atualiza
Renomear um método é simples!
- Muda o nome do método
- Procura onde é chamado e atualiza
- Roda os testes
Renomear um método é simples!
Renomear um método é simples?
- Quem chama o método vai quebrar? (conflitos de nomes)
Renomear um método é simples?
- Quem chama o método vai quebrar? (conflitos de nomes)
- Mudar o nome do método não vai quebrar outro ponto? (metaprogramação)
Renomear um método é simples?
- Quem chama o método vai quebrar? (conflitos de nomes)
- Mudar o nome do método não vai quebrar outro ponto? (metaprogramação)
- Tudo ou nada!
Refactoring vs RehacktoringREFACTORING
- Testes passam a cada mudança
REHACKTORING
- Testes talvez passem
Refactoring vs RehacktoringREFACTORING
- Testes passam a cada mudança
- Mantém comportamento externo
REHACKTORING
- Testes talvez passem
- Talvez mantém o comportamento
Refactoring vs RehacktoringREFACTORING
- Testes passam a cada mudança
- Mantém comportamento externo
- Uma mudança por vez
REHACKTORING
- Testes talvez passem
- Talvez mantém o comportamento
- Várias mudanças
Refactoring vs RehacktoringREFACTORING
- Testes passam a cada mudança
- Mantém comportamento externo
- Uma mudança por vez
- Visão clara do objetivo final
REHACKTORING
- Testes talvez passem
- Talvez mantém o comportamento
- Várias mudanças
- Objetivo final incerto
Refatoração: Renomear método1. Declare um método com o novo nome
Refatoração: Renomear método1. Declare um método com o novo nome
a. Rode os testes
Refatoração: Renomear método1. Declare um método com o novo nome
a. Rode os testes
2. Copie o código do método antigo para o novo (adaptando os parâmetros)
a. Rode os testes
Refatoração: Renomear método1. Declare um método com o novo nome
a. Rode os testes
2. Copie o código do método antigo para o novo (adaptando os parâmetros)
a. Rode os testes
3. Faça o método antigo chamar o novoa. Rode os testes
Refatoração: Renomear método1. Declare um método com o novo nome
a. Rode os testes
2. Copie o código do método antigo para o novo (adaptando os parâmetros)
a. Rode os testes
3. Faça o método antigo chamar o novoa. Rode os testes
4. Troque o método novo pelo método antigo (um por vez)
a. Rode os teste
Sério?Sério
Falta de feedback
Problemas ao refatorar
Falta de feedback
Ciclo longo
Problemas ao refatorar
Falta de feedback
Ciclo longo
Visão técnica
Problemas ao refatorar
Mão na massa: Revisar um Pull Request
Julia Carlos
Mão na massa: Revisar um Pull Request
Mão na massa: Revisar um Pull Request
Mão na massa: Revisar um Pull Request
Mão na massa: Revisar um Pull Request
Mão na massa: Revisar um Pull Request
- Outras classes vão ter preços
- Também vão precisar retornar uma string com o preço cotado
- Será necessário ter mais operações envolvendo dinheiro
- Somar, subtrair, etc.
Seu código está "ruim".Mas por quê?
Code Smells
Code Smells
Name fiveCode Smells.
Code Smells
https://martinfowler.com/bliki/CodeSmell.html
Code Smells
Code Smellshttp://mikamantyla.eu/BadCodeSmellsTaxonomy.html
Long Method
Large Class
Primitive obsession
Long Parameter List
Data Clump
Switch statements
Temporary field
Refused Bequest
Alternative classes with diff interfaces
Divergent Change
Shotgun Surgery
Parallel Inheritance
Lazy Class
Data Class
Duplicated Code
Dead Code
Speculative Generality
Feature envy
Inappropriate Intimacy
Message Chains
Middle Man
Bloatershttp://mikamantyla.eu/BadCodeSmellsTaxonomy.html
Long Method
Large Class
Primitive obsession
Long Parameter List
Data Clump
Switch statements
Temporary field
Refused Bequest
Alternative classes with diff interfaces
Divergent Change
Shotgun Surgery
Parallel Inheritance
Lazy Class
Data Class
Duplicated Code
Dead Code
Speculative Generality
Feature envy
Inappropriate Intimacy
Message Chains
Middle Man
Object Orientation Abusershttp://mikamantyla.eu/BadCodeSmellsTaxonomy.html
Long Method
Large Class
Primitive obsession
Long Parameter List
Data Clump
Switch statements
Temporary field
Refused Bequest
Alternative classes with diff interfaces
Divergent Change
Shotgun Surgery
Parallel Inheritance
Lazy Class
Data Class
Duplicated Code
Dead Code
Speculative Generality
Feature envy
Inappropriate Intimacy
Message Chains
Middle Man
Change Preventershttp://mikamantyla.eu/BadCodeSmellsTaxonomy.html
Long Method
Large Class
Primitive obsession
Long Parameter List
Data Clump
Switch statements
Temporary field
Refused Bequest
Alternative classes with diff interfaces
Divergent Change
Shotgun Surgery
Parallel Inheritance
Lazy Class
Data Class
Duplicated Code
Dead Code
Speculative Generality
Feature envy
Inappropriate Intimacy
Message Chains
Middle Man
The Couplershttp://mikamantyla.eu/BadCodeSmellsTaxonomy.html
Long Method
Large Class
Primitive obsession
Long Parameter List
Data Clump
Switch statements
Temporary field
Refused Bequest
Alternative classes with diff interfaces
Divergent Change
Shotgun Surgery
Parallel Inheritance
Lazy Class
Data Class
Duplicated Code
Dead Code
Speculative Generality
Feature envy
Inappropriate Intimacy
Message Chains
Middle Man
The Dispensableshttp://mikamantyla.eu/BadCodeSmellsTaxonomy.html
Long Method
Large Class
Primitive obsession
Long Parameter List
Data Clump
Switch statements
Temporary field
Refused Bequest
Alternative classes with diff interfaces
Divergent Change
Shotgun Surgery
Parallel Inheritance
Lazy Class
Data Class
Duplicated Code
Dead Code
Speculative Generality
Feature envy
Inappropriate Intimacy
Message Chains
Middle Man
Por onde começar?
99 Bottles of OOPhttps://www.sandimetz.com/99bottles/
Code Smell: Data Clump
https://martinfowler.com/bliki/DataClump.html
Code Smell: Data Clump
lib/series.rb
Code Smell: Data Clump
lib/series.rb
Code Smell: Data Clump
lib/series.rb
Code Smell: Data Clump
lib/series.rb
Code Smell: Data Clump
lib/series.rb
Mão na massa: introduzir Value Class
1. Criar uma Value Class com construtores e gettersa. Deve incluir o valor e a moeda
2. Encapsular atributos ao invés de chamá-las diretamente
3. Instanciar Value Object junto com os atributos
4. Trocar chamada getter por getter da Value Class
5. Apagar atributos não utilizados
Value Class para representar dinheiro
lib/series.rb
Value Class para representar dinheiro
lib/dinheiro.rb
Value Class para representar dinheiro
lib/dinheiro.rb
Value Class para representar dinheiro
lib/dinheiro.rb
Encapsular atributos preco e moeda
lib/serie.rb
Encapsular atributos preco e moeda
lib/serie.rb
Encapsular atributos preco e moeda
lib/serie.rb
Encapsular atributos preco e moeda
lib/serie.rb
Encapsular atributos preco e moeda
lib/serie.rb
Instanciar Value Object junto com atributos
lib/serie.rb
Instanciar Value Object junto com atributos
lib/serie.rb
Instanciar Value Object junto com atributos
lib/serie.rb
Trocar chamada do getter pela value class
lib/serie.rb
Trocar chamada do getter pela value class
lib/serie.rb
Trocar chamada do getter pela value class
lib/serie.rb
Apagar atributos não utilizados
lib/serie.rb
Apagar atributos não utilizados
lib/serie.rb
Apagar atributos não utilizados
lib/serie.rb
Apagar atributos não utilizados
lib/serie.rb
Apagar atributos não utilizados
lib/serie.rb
Apagar atributos não utilizados
lib/serie.rb
Code Smell: Primitive Obsession
http://wiki.c2.com/?PrimitiveObsession
Code Smell: Primitive Obsession
lib/cotacao_util.rb
lib/serie.rb
Code Smell: Primitive Obsession
lib/cotacao_util.rb
lib/serie.rb
Mão na massa: introduzir Parameter Object1. Criar uma estrutura para agrupar parâmetros (se não existir)
2. Mudar a assinatura do métodoa. Criar um método com mesmo corpo e nova assinatura
b. Atualizar referências ao novo parâmetro
3. Chamar o método novo no método antigo
4. Atualizar as referências do métodos antigos
5. Apagar método antigo
Criar uma estrutura para agrupar parâmetros
lib/dinheiro.rb
Mudar a assinatura do método
lib/cotacao_util.rb
Mudar a assinatura do método
lib/cotacao_util.rb
Mudar a assinatura do método
lib/cotacao_util.rb
Mudar a assinatura do método
lib/cotacao_util.rb
Mudar a assinatura do método
lib/cotacao_util.rb
Mudar a assinatura do método
lib/cotacao_util.rb
Atualizar as referências do método antigo
lib/serie.rb
Atualizar as referências do método antigo
lib/serie.rb
Apagar método antigo
Code Smell: Feature Envy
http://wiki.c2.com/?FeatureEnvySmell
Code Smell: Feature Envy
lib/serie.rb
Code Smell: Feature Envy
lib/serie.rb
Code Smell: Feature Envy
lib/serie.rb
Code Smell: Feature Envy
lib/serie.rb
Mão na massa: mover método
1. Identificar e extrair o método que será movidoa. Copiar conteúdo para novo método
b. Converter variáveis locais em parâmetro
2. Copiar método para nova classea. trocar parâmetros por atributos (quando possível)
3. Trocar chamadas do método antigo pelo novo método
4. Apagar métodos antigos
Identificar e extrair o método que será movido
lib/serie.rb
Identificar e extrair o método que será movido
lib/serie.rb
Identificar e extrair o método que será movido
lib/serie.rb
Identificar e extrair o método que será movido
lib/serie.rb
Copiar método para nova classe
lib/dinheiro.rb
Copiar método para nova classe
lib/dinheiro.rb
Copiar método para nova classe
lib/dinheiro.rb
Trocar chamadas pelo método novo
lib/serie.rb
Trocar chamadas pelo método novo
lib/serie.rb
Trocar chamadas pelo método novo
lib/serie.rb
Apagar método antigo
Code Smell: Feature Envy
lib/serie.rb
lib/cotacao_util.rb
Code Smell: Feature Envy
lib/serie.rb
lib/cotacao_util.rb
Code Smell: Feature Envy
lib/serie.rb
lib/cotacao_util.rb
Classes Util/Service e Orientação a Objetos
Objetos se comunicam através de mensagens, visando protegere esconder seu estado interno
Pensando orientado a objetos
Dinheiro
valor: intmoeda: String
exibir_moedaconverter_moedasomar...
Estados
Mensagens
Pensando orientado a objetos
obj
obj
obj
obj
obj
obj
Code Smell: Data Class
Dinheiro
valor: intmoeda: String
getValor: intsetValor: voidgetMoeda: StringsetMoeda: void
Estados
Mensagens
DinheiroService
exibir_moedaconverter_moedasomar...
Objetos anêmicos Serviços/Util
Programação Procedural
Proragamação Procedural é ruim?
Usar uma linguagem OO para programar procedural é ruim!
Code Smell: Feature Envy
lib/serie.rb
lib/cotacao_util.rb
Mão na massa: mover método
1. Identificar e extrair o método que será movidoa. Copiar conteúdo para novo método
b. Converter variáveis locais em parâmetro
2. Copiar método para nova classea. trocar parâmetros por atributos (quando possível)
3. Trocar chamadas do método antigo pelo novo método
4. Apagar métodos antigos
Identificar e extrair o método que será movido
lib/serie.rb
Identificar e extrair o método que será movido
lib/serie.rb
Identificar e extrair o método que será movido
lib/serie.rb
Copiar método para nova classe
lib/dinheiro.rb
Copiar método para nova classe
lib/dinheiro.rb
Trocar chamadas pelo método novo
lib/serie.rb
Trocar chamadas pelo método novo
lib/serie.rb
Trocar chamadas pelo método novo
lib/serie.rb
Apagar método antigo
Como decidir o que depende do que?
Quantidade de mudanças e acomplamento
https://www.youtube.com/watch?v=v-2yFMzxqwU
Probabilidade de mudanças
Quantidade de mudanças e acomplamento
https://www.youtube.com/watch?v=v-2yFMzxqwU
Probabilidade de mudanças
Cotacao Dinheiro
Extrair os valores da cotação para um arquivo de configuração
Quantidade de mudanças e acomplamento
https://www.youtube.com/watch?v=v-2yFMzxqwU
Probabilidade de mudanças
Dependa da direita para a esquerda
Cotacao Dinheiro
Como melhorar seu código efetivamente
1. Entenda como seu programa vai evoluir (Keep it Simple, Stupid)
2. Identifique os Code Smells mais fáceis de resolver
3. Aplique refatorações
4. Repita até que o código esteja aberto a extensão
5. Aplique a mudança
Garantir que ostestes sempre passem
Feedback rápido
Garantir que ostestes sempre passem
Feedback rápido
Fácil de reverter
Garantir que ostestes sempre passem
Feedback rápido
Fácil de reverter
Reduz ansiedade
Code Smell -> Refactoring
https://refactoring.com/catalog/
Code Smell -> Refactoring
industriallogic.com/blog/smells-to-refactorings-cheatsheet/
Code Smell é ruim?
Simplicidade de código
Extreme Programming Explained: embrace change
Todos os testes passam
Sem duplicac ao
Mostra as intenc oes
Possui o menor numero de classes ou metodos
Mais!
Refactoring
- Martin Fowler
Mais!
99 Bottles of Object Oriented Programming
- Sandi Metz & Katrina Owen
Mais!
Refatorando com Padrões de Projeto
- Marcos Brizeno
Mais!
Refatorando com Padrões de Projeto
- Marcos Brizeno
20% - DIADOPROGRAMADOR_2017X
https://www.casadocodigo.com.br/products/livro-refatoracao-ruby
Valeu!@marcosbrizeno