Refatorando tudo! [Agile brazil 2017]

164
Refatorando TUDO! @marcosbrizeno

Transcript of Refatorando tudo! [Agile brazil 2017]

Page 1: Refatorando tudo! [Agile brazil 2017]

Refatorando TUDO!

@marcosbrizeno

Page 2: Refatorando tudo! [Agile brazil 2017]

@marcosbrizeno

Page 3: Refatorando tudo! [Agile brazil 2017]

A única maneirade ir rápidoé ter qualidade

Page 4: Refatorando tudo! [Agile brazil 2017]
Page 5: Refatorando tudo! [Agile brazil 2017]

https://pt.wikipedia.org/wiki/Procrastinação

Page 6: Refatorando tudo! [Agile brazil 2017]

tempo

esforço

Page 7: Refatorando tudo! [Agile brazil 2017]

prazo

tempo

esforço

Page 8: Refatorando tudo! [Agile brazil 2017]

tempo

esforço

Page 9: Refatorando tudo! [Agile brazil 2017]

O Scrum resolve esse problema!

Page 10: Refatorando tudo! [Agile brazil 2017]

tempo

esforço

...

Page 11: Refatorando tudo! [Agile brazil 2017]

Iteração 1 Iteração 2 Iteração n...

...

tempo

esforço

Page 12: Refatorando tudo! [Agile brazil 2017]

You can't ship process

Page 13: Refatorando tudo! [Agile brazil 2017]

A única maneirade ir rápidoé ter qualidade

https://www.youtube.com/watch?v=hG4LH6P8Syk

Page 14: Refatorando tudo! [Agile brazil 2017]

Mão na massa: Renomear um método

Page 15: Refatorando tudo! [Agile brazil 2017]

Mão na massa: Renomear um método

Page 16: Refatorando tudo! [Agile brazil 2017]
Page 17: Refatorando tudo! [Agile brazil 2017]

Renomear um método é simples!

Page 18: Refatorando tudo! [Agile brazil 2017]

Renomear um método é simples!

- Muda o nome do método

Page 19: Refatorando tudo! [Agile brazil 2017]

Renomear um método é simples!

- Muda o nome do método

- Procura onde é chamado e atualiza

Page 20: Refatorando tudo! [Agile brazil 2017]

Renomear um método é simples!

- Muda o nome do método

- Procura onde é chamado e atualiza

- Roda os testes

Page 21: Refatorando tudo! [Agile brazil 2017]

Renomear um método é simples!

Page 22: Refatorando tudo! [Agile brazil 2017]

Renomear um método é simples?

- Quem chama o método vai quebrar? (conflitos de nomes)

Page 23: Refatorando tudo! [Agile brazil 2017]

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)

Page 24: Refatorando tudo! [Agile brazil 2017]

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!

Page 25: Refatorando tudo! [Agile brazil 2017]

Refactoring vs RehacktoringREFACTORING

- Testes passam a cada mudança

REHACKTORING

- Testes talvez passem

Page 26: Refatorando tudo! [Agile brazil 2017]

Refactoring vs RehacktoringREFACTORING

- Testes passam a cada mudança

- Mantém comportamento externo

REHACKTORING

- Testes talvez passem

- Talvez mantém o comportamento

Page 27: Refatorando tudo! [Agile brazil 2017]

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

Page 28: Refatorando tudo! [Agile brazil 2017]

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

Page 29: Refatorando tudo! [Agile brazil 2017]

Refatoração: Renomear método1. Declare um método com o novo nome

Page 30: Refatorando tudo! [Agile brazil 2017]

Refatoração: Renomear método1. Declare um método com o novo nome

a. Rode os testes

Page 31: Refatorando tudo! [Agile brazil 2017]

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

Page 32: Refatorando tudo! [Agile brazil 2017]

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

Page 33: Refatorando tudo! [Agile brazil 2017]

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

Page 34: Refatorando tudo! [Agile brazil 2017]

Sério?Sério

Page 35: Refatorando tudo! [Agile brazil 2017]
Page 36: Refatorando tudo! [Agile brazil 2017]

Falta de feedback

Problemas ao refatorar

Page 37: Refatorando tudo! [Agile brazil 2017]

Falta de feedback

Ciclo longo

Problemas ao refatorar

Page 38: Refatorando tudo! [Agile brazil 2017]

Falta de feedback

Ciclo longo

Visão técnica

Problemas ao refatorar

Page 39: Refatorando tudo! [Agile brazil 2017]

Mão na massa: Revisar um Pull Request

Julia Carlos

Page 40: Refatorando tudo! [Agile brazil 2017]

Mão na massa: Revisar um Pull Request

Page 41: Refatorando tudo! [Agile brazil 2017]

Mão na massa: Revisar um Pull Request

Page 42: Refatorando tudo! [Agile brazil 2017]

Mão na massa: Revisar um Pull Request

Page 43: Refatorando tudo! [Agile brazil 2017]

Mão na massa: Revisar um Pull Request

Page 44: Refatorando tudo! [Agile brazil 2017]
Page 45: Refatorando tudo! [Agile brazil 2017]

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.

Page 46: Refatorando tudo! [Agile brazil 2017]
Page 47: Refatorando tudo! [Agile brazil 2017]

Seu código está "ruim".Mas por quê?

Page 48: Refatorando tudo! [Agile brazil 2017]

Code Smells

Page 49: Refatorando tudo! [Agile brazil 2017]

Code Smells

Name fiveCode Smells.

Page 50: Refatorando tudo! [Agile brazil 2017]

Code Smells

https://martinfowler.com/bliki/CodeSmell.html

Page 51: Refatorando tudo! [Agile brazil 2017]

Code Smells

Page 52: Refatorando tudo! [Agile brazil 2017]

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

Page 53: Refatorando tudo! [Agile brazil 2017]

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

Page 54: Refatorando tudo! [Agile brazil 2017]

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

Page 55: Refatorando tudo! [Agile brazil 2017]

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

Page 56: Refatorando tudo! [Agile brazil 2017]

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

Page 57: Refatorando tudo! [Agile brazil 2017]

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

Page 58: Refatorando tudo! [Agile brazil 2017]

Por onde começar?

99 Bottles of OOPhttps://www.sandimetz.com/99bottles/

Page 59: Refatorando tudo! [Agile brazil 2017]

Code Smell: Data Clump

https://martinfowler.com/bliki/DataClump.html

Page 60: Refatorando tudo! [Agile brazil 2017]

Code Smell: Data Clump

lib/series.rb

Page 61: Refatorando tudo! [Agile brazil 2017]

Code Smell: Data Clump

lib/series.rb

Page 62: Refatorando tudo! [Agile brazil 2017]

Code Smell: Data Clump

lib/series.rb

Page 63: Refatorando tudo! [Agile brazil 2017]

Code Smell: Data Clump

lib/series.rb

Page 64: Refatorando tudo! [Agile brazil 2017]

Code Smell: Data Clump

lib/series.rb

Page 65: Refatorando tudo! [Agile brazil 2017]

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

Page 66: Refatorando tudo! [Agile brazil 2017]
Page 67: Refatorando tudo! [Agile brazil 2017]

Value Class para representar dinheiro

lib/series.rb

Page 68: Refatorando tudo! [Agile brazil 2017]

Value Class para representar dinheiro

lib/dinheiro.rb

Page 69: Refatorando tudo! [Agile brazil 2017]

Value Class para representar dinheiro

lib/dinheiro.rb

Page 70: Refatorando tudo! [Agile brazil 2017]

Value Class para representar dinheiro

lib/dinheiro.rb

Page 71: Refatorando tudo! [Agile brazil 2017]

Encapsular atributos preco e moeda

lib/serie.rb

Page 72: Refatorando tudo! [Agile brazil 2017]

Encapsular atributos preco e moeda

lib/serie.rb

Page 73: Refatorando tudo! [Agile brazil 2017]

Encapsular atributos preco e moeda

lib/serie.rb

Page 74: Refatorando tudo! [Agile brazil 2017]

Encapsular atributos preco e moeda

lib/serie.rb

Page 75: Refatorando tudo! [Agile brazil 2017]

Encapsular atributos preco e moeda

lib/serie.rb

Page 76: Refatorando tudo! [Agile brazil 2017]

Instanciar Value Object junto com atributos

lib/serie.rb

Page 77: Refatorando tudo! [Agile brazil 2017]

Instanciar Value Object junto com atributos

lib/serie.rb

Page 78: Refatorando tudo! [Agile brazil 2017]

Instanciar Value Object junto com atributos

lib/serie.rb

Page 79: Refatorando tudo! [Agile brazil 2017]

Trocar chamada do getter pela value class

lib/serie.rb

Page 80: Refatorando tudo! [Agile brazil 2017]

Trocar chamada do getter pela value class

lib/serie.rb

Page 81: Refatorando tudo! [Agile brazil 2017]

Trocar chamada do getter pela value class

lib/serie.rb

Page 82: Refatorando tudo! [Agile brazil 2017]

Apagar atributos não utilizados

lib/serie.rb

Page 83: Refatorando tudo! [Agile brazil 2017]

Apagar atributos não utilizados

lib/serie.rb

Page 84: Refatorando tudo! [Agile brazil 2017]

Apagar atributos não utilizados

lib/serie.rb

Page 85: Refatorando tudo! [Agile brazil 2017]

Apagar atributos não utilizados

lib/serie.rb

Page 86: Refatorando tudo! [Agile brazil 2017]

Apagar atributos não utilizados

lib/serie.rb

Page 87: Refatorando tudo! [Agile brazil 2017]

Apagar atributos não utilizados

lib/serie.rb

Page 88: Refatorando tudo! [Agile brazil 2017]

Code Smell: Primitive Obsession

http://wiki.c2.com/?PrimitiveObsession

Page 89: Refatorando tudo! [Agile brazil 2017]

Code Smell: Primitive Obsession

lib/cotacao_util.rb

lib/serie.rb

Page 90: Refatorando tudo! [Agile brazil 2017]

Code Smell: Primitive Obsession

lib/cotacao_util.rb

lib/serie.rb

Page 91: Refatorando tudo! [Agile brazil 2017]

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

Page 92: Refatorando tudo! [Agile brazil 2017]
Page 93: Refatorando tudo! [Agile brazil 2017]

Criar uma estrutura para agrupar parâmetros

lib/dinheiro.rb

Page 94: Refatorando tudo! [Agile brazil 2017]

Mudar a assinatura do método

lib/cotacao_util.rb

Page 95: Refatorando tudo! [Agile brazil 2017]

Mudar a assinatura do método

lib/cotacao_util.rb

Page 96: Refatorando tudo! [Agile brazil 2017]

Mudar a assinatura do método

lib/cotacao_util.rb

Page 97: Refatorando tudo! [Agile brazil 2017]

Mudar a assinatura do método

lib/cotacao_util.rb

Page 98: Refatorando tudo! [Agile brazil 2017]

Mudar a assinatura do método

lib/cotacao_util.rb

Page 99: Refatorando tudo! [Agile brazil 2017]

Mudar a assinatura do método

lib/cotacao_util.rb

Page 100: Refatorando tudo! [Agile brazil 2017]

Atualizar as referências do método antigo

lib/serie.rb

Page 101: Refatorando tudo! [Agile brazil 2017]

Atualizar as referências do método antigo

lib/serie.rb

Page 102: Refatorando tudo! [Agile brazil 2017]

Apagar método antigo

Page 103: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

http://wiki.c2.com/?FeatureEnvySmell

Page 104: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

lib/serie.rb

Page 105: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

lib/serie.rb

Page 106: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

lib/serie.rb

Page 107: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

lib/serie.rb

Page 108: Refatorando tudo! [Agile brazil 2017]

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

Page 109: Refatorando tudo! [Agile brazil 2017]
Page 110: Refatorando tudo! [Agile brazil 2017]

Identificar e extrair o método que será movido

lib/serie.rb

Page 111: Refatorando tudo! [Agile brazil 2017]

Identificar e extrair o método que será movido

lib/serie.rb

Page 112: Refatorando tudo! [Agile brazil 2017]

Identificar e extrair o método que será movido

lib/serie.rb

Page 113: Refatorando tudo! [Agile brazil 2017]

Identificar e extrair o método que será movido

lib/serie.rb

Page 114: Refatorando tudo! [Agile brazil 2017]

Copiar método para nova classe

lib/dinheiro.rb

Page 115: Refatorando tudo! [Agile brazil 2017]

Copiar método para nova classe

lib/dinheiro.rb

Page 116: Refatorando tudo! [Agile brazil 2017]

Copiar método para nova classe

lib/dinheiro.rb

Page 117: Refatorando tudo! [Agile brazil 2017]

Trocar chamadas pelo método novo

lib/serie.rb

Page 118: Refatorando tudo! [Agile brazil 2017]

Trocar chamadas pelo método novo

lib/serie.rb

Page 119: Refatorando tudo! [Agile brazil 2017]

Trocar chamadas pelo método novo

lib/serie.rb

Page 120: Refatorando tudo! [Agile brazil 2017]

Apagar método antigo

Page 121: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

lib/serie.rb

lib/cotacao_util.rb

Page 122: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

lib/serie.rb

lib/cotacao_util.rb

Page 123: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

lib/serie.rb

lib/cotacao_util.rb

Page 124: Refatorando tudo! [Agile brazil 2017]

Classes Util/Service e Orientação a Objetos

Page 125: Refatorando tudo! [Agile brazil 2017]

Objetos se comunicam através de mensagens, visando protegere esconder seu estado interno

Page 126: Refatorando tudo! [Agile brazil 2017]

Pensando orientado a objetos

Dinheiro

valor: intmoeda: String

exibir_moedaconverter_moedasomar...

Estados

Mensagens

Page 127: Refatorando tudo! [Agile brazil 2017]

Pensando orientado a objetos

obj

obj

obj

obj

obj

obj

Page 128: Refatorando tudo! [Agile brazil 2017]

Code Smell: Data Class

Dinheiro

valor: intmoeda: String

getValor: intsetValor: voidgetMoeda: StringsetMoeda: void

Estados

Mensagens

DinheiroService

exibir_moedaconverter_moedasomar...

Page 129: Refatorando tudo! [Agile brazil 2017]

Objetos anêmicos Serviços/Util

Programação Procedural

Page 130: Refatorando tudo! [Agile brazil 2017]

Proragamação Procedural é ruim?

Page 131: Refatorando tudo! [Agile brazil 2017]

Usar uma linguagem OO para programar procedural é ruim!

Page 132: Refatorando tudo! [Agile brazil 2017]
Page 133: Refatorando tudo! [Agile brazil 2017]

Code Smell: Feature Envy

lib/serie.rb

lib/cotacao_util.rb

Page 134: Refatorando tudo! [Agile brazil 2017]

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

Page 135: Refatorando tudo! [Agile brazil 2017]
Page 136: Refatorando tudo! [Agile brazil 2017]

Identificar e extrair o método que será movido

lib/serie.rb

Page 137: Refatorando tudo! [Agile brazil 2017]

Identificar e extrair o método que será movido

lib/serie.rb

Page 138: Refatorando tudo! [Agile brazil 2017]

Identificar e extrair o método que será movido

lib/serie.rb

Page 139: Refatorando tudo! [Agile brazil 2017]

Copiar método para nova classe

lib/dinheiro.rb

Page 140: Refatorando tudo! [Agile brazil 2017]

Copiar método para nova classe

lib/dinheiro.rb

Page 141: Refatorando tudo! [Agile brazil 2017]

Trocar chamadas pelo método novo

lib/serie.rb

Page 142: Refatorando tudo! [Agile brazil 2017]

Trocar chamadas pelo método novo

lib/serie.rb

Page 143: Refatorando tudo! [Agile brazil 2017]

Trocar chamadas pelo método novo

lib/serie.rb

Page 144: Refatorando tudo! [Agile brazil 2017]

Apagar método antigo

Page 145: Refatorando tudo! [Agile brazil 2017]

Como decidir o que depende do que?

Page 146: Refatorando tudo! [Agile brazil 2017]

Quantidade de mudanças e acomplamento

https://www.youtube.com/watch?v=v-2yFMzxqwU

Probabilidade de mudanças

Page 147: Refatorando tudo! [Agile brazil 2017]

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

Page 148: Refatorando tudo! [Agile brazil 2017]

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

Page 149: Refatorando tudo! [Agile brazil 2017]
Page 150: Refatorando tudo! [Agile brazil 2017]

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

Page 151: Refatorando tudo! [Agile brazil 2017]

Garantir que ostestes sempre passem

Feedback rápido

Page 152: Refatorando tudo! [Agile brazil 2017]

Garantir que ostestes sempre passem

Feedback rápido

Fácil de reverter

Page 153: Refatorando tudo! [Agile brazil 2017]

Garantir que ostestes sempre passem

Feedback rápido

Fácil de reverter

Reduz ansiedade

Page 154: Refatorando tudo! [Agile brazil 2017]

Code Smell -> Refactoring

https://refactoring.com/catalog/

Page 155: Refatorando tudo! [Agile brazil 2017]

Code Smell -> Refactoring

industriallogic.com/blog/smells-to-refactorings-cheatsheet/

Page 156: Refatorando tudo! [Agile brazil 2017]

Code Smell é ruim?

Page 157: Refatorando tudo! [Agile brazil 2017]

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

Page 158: Refatorando tudo! [Agile brazil 2017]

Mais!

Refactoring

- Martin Fowler

Page 159: Refatorando tudo! [Agile brazil 2017]

Mais!

99 Bottles of Object Oriented Programming

- Sandi Metz & Katrina Owen

Page 160: Refatorando tudo! [Agile brazil 2017]

Mais!

Refatorando com Padrões de Projeto

- Marcos Brizeno

Page 161: Refatorando tudo! [Agile brazil 2017]

Mais!

Refatorando com Padrões de Projeto

- Marcos Brizeno

Page 162: Refatorando tudo! [Agile brazil 2017]

20% - DIADOPROGRAMADOR_2017X

https://www.casadocodigo.com.br/products/livro-refatoracao-ruby

Page 163: Refatorando tudo! [Agile brazil 2017]
Page 164: Refatorando tudo! [Agile brazil 2017]

Valeu!@marcosbrizeno