SlideShare una empresa de Scribd logo
1 de 91
Descargar para leer sin conexión
Desenvolvimento
Baseado em Testes
Refatoração
Agenda
• Refatoração	

• Exemplos	

• Técnicas de Refatoração
2
Refatoração
O que é?
• “É o processo de realizar mudanças
em código existente e funcional sem
alterar seu comportamento”	

!

• Alterar COMO o código	

• NÃO alterar O QUE ele faz	

!

• Aprimorar a estrutura interna
Qual a relação com
TDD?
Refatoração
e TDD
• Após implementar o código mais simples
para fazer o teste passar	


• refatoramos o código para remover as

duplicações que adicionamos para ver o
teste passar	


• Como temos um conjunto seguro de
testes,	


• então podemos refatorar com confiança
O que nos motiva a
refatorar?
Motivação
• facilitar a adição de código novo	

• melhorar o projeto existente	

• obter um melhor entendimento de código	

• tornar a programação menos irritante
Quando refatorar?
Contextos
• quando existe duplicação de código	

• quando a intenção é obscura
• percebemos que o código e/ou sua
intenção não são claros

• ex: lógica condicional complicada	


• quando detectamos problemas de código
(“bad smells”)	


• ou indícios de problemas
Duplicação
• Falência de um bom código	

• Existem várias formas	

• simples e óbvios	

• índícios	

• disfarçados
Say Everything Once and Only Once
!

Don’t Repeat Yourself
Diga tudo uma vez e apenas uma vez
!

Não se repita
Exemplos
Duplicação: 1.º exemplo
def save	
	 if (arquivo.nil?)	
	 	 return false	
	 end	
	 diretorio = Diretorio.new(arquivo)	
	 diretorio.add(arquivo)	
	 diretorio.close()	
	 return true	
end	

	
	
	
	
	
	
	
	
	
	

def saveAs	
	 arquivo = view.file	
	 	
	 if (arquivo.nil?) 	
	 	 return false	
	 end	
	 diretorio = Diretorio.new(arquivo)	
	 diretorio.add(arquivo)	
	 diretorio.close()	
	 return true	
end
def save	
	 if (arquivo.nil?) {	
	 	 return false	
	 }	
	 diretorio = Diretorio.new(arquivo)	
	 diretorio.add(arquivo)	
	 diretorio.close()	
	 return true	
end	

	
	
	
	

def saveAs	
	 arquivo = view.file	
	 	
	 save	
end
Duplicação: 2.º exemplo
class MovieList 	
	 def initialize	
	 	 @movies = []	
	 	 @number_of_movies = 0	
	 end	
	 	
	 def size	
	 	 @movies.size	
	 end	
	 	
	 def add movie_to_add	
	 	 @movies  movie_to_add	
	 	 @number_of_movies = @number_of_movies + 1	
	 end	
end
class MovieList 	
!
	 def initialize	
	 	 @movies = []	
	 	 @number_of_movies = 0	
	 end	

!
def size	 	
	 @movies.size	
end	
	
def add movie_to_add 	
@movies  movie_to_add	
end	
!
end
Intenção obscura
O que torna um código
claro?
• Escolher bons nomes
• dicionário na mão para ajudar a
comunicar nossa intenção	


• TDD	

• Como escrevemos 1º o teste, somos
forçados a pensar na interface do
código antes da sua implementação	


• oportunidade de pensar a partir do

ponto de vista do usuário da classe
Problemas de código
Code Smells
Bad Smells
•
•
•
•

Excesso de comentários	

Classes de dados	

Código duplicado	

Intimidade inapropriada	

!
!
!

•
•
•
•

Classes muito grandes	

Classes “preguiçosas”	

Métodos longos	

Switches
Excesso de
comentários
def init
// set the layout
content_pane.layout(FlowLayout.new)
!
// create the list
movie_list = List.new(my_editor.movies)
scroller = ScrollPane.new(movie_list)
content_pane.add(scroller)
!
// create the field
movie_field = TextField.new(16)
content_pane.add(movie_field)
!
// create theadd button
add_button = Button.new(“Add)
....
end
Classes de dados
class Ponto 	
	 attr_accessor :x, :y	
	 	
	 def initialize(x = 0, y = 0) 	
	 	 @x = x;	
	 	 @y = y;	
	 end	
	 	
end
Com intimidade
def temperatura
t = estacao.termometro
t.temperatura
end
Sem intimidade
def temperatura
estacao.temperatura
end
Classes muito grandes
• Desproporcional às outras	

• Por quê?	

• tenta fazer muita coisa?	

• possui muito código condicional?	

• possui muito comportamento
condicional?	


• Como identificar?
Classes “preguiçosas”

• Classes tão pequentas que não justificam
sua existência	


• Devem ser fundidas à outras classes
Switches
class Empregado
// 0 - engenheiro, 1 - vendedor, 2 - gerente
attr_accessor :tipo_empregado
!

def nome_do_departamento
case @tipo_empregado
when 0
return Engenheiro
when 1	

return Vendedor
when 2
return Gerente
else
return Desconhecido
end
end
end
Dica
•

Princípios de Orientação
a objetos	


•

Design Patterns
Como refatorar?
Como refatorar
1. Estrutura de testes que proporcionem
feedback	

2. Pequenos passos	

3. IDEs
Técnicas de refatoração
Refatorações
•
•
•
•
•

Extrair classe	

Extrair interface	

Extrair método	

Substituir código
digitado por subclasses
ou objeto de valor	

Substituir condicional
por polimorfismo	


•

Utilizar métodos
gabaritos	


•

Utilizar variavel
explicativa	


•

Substituir construtores
por métodos fábrica	


•

Substituir herança por
delegação	


•

Substituir números
mágicos por constantes
Extrair Classe
• Contexto	

• classes muito grandes	

• comportamento disperso	

• Solução	

• fracionar as classes em pedaços menores
mais coesos	


• Extração de comportamentos para uma
nova classe
class MovieListWriter 	
	 attr_accessor :destination	

!
	
	
	

def initialize(aWriter = nil) 	
	 destination = aWriter;	
end	

!
	
	
	
	
	

def write_movie_list(a_list) 	
	 a_list.movies.each do |movie|	
	 	 write_movie(movie)	
	 end	
	 	
end	

!
	 def write_movie(a_movie)	
	 	 destination.write(a_movie.name)	
	 	 destination.write('|')	
	 	 destination.write(a_movie.category.to_s)	
	 	 destination.write('|')	
	 	 begin	
	 	 	 destination.write(a_movie.rating.to_s)	
	 	 rescue UnratedException = ex	
	 	 	 destination.write(-1)	
	 	 end	
	 	 destination.write('n')	
	 end	
end
class Movie 	
	 // ...	
	 def write_to(destination)

	
	 	 destination.write(name)	
	 	 destination.write('|')	
	 	 destination.write(category.to_s)	
	 	 destination.write('|')	
	 	 begin 	
	 	 	 destination.write(rating.to_s)	
	 	 rescue UnratedException = ex	
	 	 	 destination.write(-1)	
	 	 end	
	 	 destination.write('n');	
	 end	
	 // ...	
end
class MovieList 	
	 	
	 write_to(destination)

	 	 	 movies.each do |movie|	
	 	 	 	 movie.write_to(destination)	
	 	 	 end	
	 end	 	
end
Extrair Interface
• Contexto	

• Se quer abstrair a forma de uma
implementação concreta	


• Comportamentos importantes
substituíveis ou reversíveis	


• Solução	

• criar interfaces para poder substituir o
concreto tardiamente
public class MovieList {	
	 private CollectionMovie movies =	
	 	 new ArrayListMovie();	
!

	
	
	
	
	
	
	
}

public int size() {	
	 return movies.size();	
}	
	
public void add(Movie movieToAdd) {	
	
movies.add(movieToAdd);	
}
public interface IMovieList {	
!

	 public abstract int size();	
!

	 public abstract void add(Movie movie);	
!

}
public class MovieList

implements IMovieList {	
//...	
}
Strategy
Extrair Método
• Contexto	

• métodos muito longos	

• lógicas de complexo entendimento	

• Solução	

• fracionar o método em métodos
menores mais coesos	


• Extração de comportamentos para novos
métodos
public void init() {

}

getContentPane().setLayout(new FlowLayout());
movieList = new JList(myEditor.getMovies());
JScrollPane scroller = new JScrollPane(movieList);
getContentPane().add(scroller);
movieField = new JTextField(16);
getContentPane().add(movieField);
addButton = new JButton(Add);
....
public void init() {
// set the layout
getContentPane().setLayout(new FlowLayout());
!
// create the list
movieList = new JList(myEditor.getMovies());
JScrollPane scroller = new JScrollPane(movieList);
getContentPane().add(scroller);
!
// create the field
movieField = new JTextField(16);
getContentPane().add(movieField);
!
// create theadd button
addButton = new JButton(Add);
....
}
public void init() {
setLayout();
initMovieList();
initMovieField();
initAddButton();
}	

private void setLayout() {
getContentPane().setLayout(new FlowLayout());
}	

private void initMovieList() {
movieList = new JList(getMovies());
JScrollPane scroller = new JScrollPane(movieList);
getContentPane().add(scroller);
}	

private void initMovieField() {
movieField = new JTextField(16);
getContentPane().add(movieField);
}	

private void initAddButton() {...
Extrair Método 2
• Se um trecho de código duplicado
diferentes do programa
Classe1
Extrair Método 2
•

Se as duplicatas de código devem permanecer
sempre iguais, ou seja, uma vez que se realize uma
alteração em uma delas, as demais devem refletir
a alteração
Classe1
public void doGet(HttpservletRequest request,
HttpServletResponse response)
throws ServletException, IOException{
String p = request.getParameter(“personagem”);
request.setAttribute(“personagem”, p);
//Mais código
}
!
public void doPost(HttpservletRequest request,
HttpServletResponse response)
throws ServletException, IOException{
String p = request.getParameter(“personagem”);
request.setAttribute(“personagem”, p);
//Mais código
}
•

Extraindo o método

Concentre o código que se repete em um único
lugar, por exemplo, em um método e leve as
dependências para lá

public void doGet(HtttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException{
String p = request.getParameter(“personagem”);
request.setAttribute(“personagem”, p);
//Mais código
}
public void novoMetodo(HtttpServletRequest request,
HttpServletResponse response)throws ServletException,
IOException{
String p = request.getParameter(“personagem”);
request.setAttribute(“personagem”, p);
//Mais código
}
public void novoMetodo(HttpServletRequest
request, HttpServletResponse response)
throws ServletException, IOException{
.....
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException{
novoMetodo(request, response);
}
!

public void doPost(HttpservletRequest
request, HttpServletResponse response)
throws ServletException, IOException{
novoMetodo(request, response);
}
Refatorações
•
•
•
•
•

Extrair classe	

Extrair interface	

Extrair método	

Substituir código
digitado por subclasses
ou objetos de valor	

Substituir condicional
por polimorfismo	


•

Utilizar métodos
gabaritos	


•

Utilizar variavel
explicativa	


•

Substituir construtores
por métodos fábrica	


•

Substituir herança por
delegação	


•

Substituir números
mágicos por constantes
Substituir código
digitado por subclasses
• Contexto	

• classes indicam subtipos através de
código digitado	


• Solução	

• Criar uma subclasse para cada alternativa	

• Vantagem	

• Evitam-se complexos condicionais
class Empregado 	
	 //0 - engenheiro, 1 - vendedor, 2 - gerente	
	 attr_accessor :tipo_do_empregado	
	 //..	
end
class Empregado 	
	 // ...	
end	
!

class Engenheiro  Empregado 	
	 // ...	
end	
!

class Vendedor  Empregado 	
	 // ...	
end	
!

class Gerente  Empregado 	
	 // ...	
end
Substituir condicional
por polimorfismo	

• Contexto	

• classes indicam subtipos através de
código digitado	


• Solução	

• Criar uma subclasse para cada alternativa	

• Vantagem	

• Evitam-se complexos condicionais
public class Empregado 	
	 // 0 - engenheiro, 1 - vendedor, 2 - gerente	
	 attr_accessor :tipo_do_empregado	
!

	 def nome_do_departamento	
	 	 case @tipoDoEmpregado	
	 	 	 when 0	
	 	 	 	 return Engenharia	
	 	 	 when 1	
	 	 	 	 return Vendas	
	 	 	 when 2	
	 	 	 	 return Gerência	
	 	 	 else	
	 	 	 	 return Desconhecido	
	 	 end	
	 end	
end
class Empregado 	
	 def nome_do_departamento	
	 end	
end	
!
class Engenheiro  Empregado 	
	 def nome_do_departamento	
	
Engenharia	
end	
end	
!
class Vendedor  Empregado 	
	 def nome_do_departamento	
	 	 Vendas	
end	
end	
!
class Gerente extends Empregado 	
	 def nome_do_departamento	
	
Gerência	
end	
end
Utilizar métodos
gabaritos	

•

•

Contexto	


•

métodos em subclasses executam passos
similares na mesma ordem

•

os passos são diferentes	


Solução	


•

extraia os passos para métodos com mesma
assinatura	


•
•

crie um método gabarito final na superclasse	

especialize os métodos nas subclasses
Contexto
public class Cafe {
public void prepararReceita(){
ferverAgua();
misturarCafeComAgua();
servirNaXicara();
adicionarAcucarELeite();
}

!
!
!
!
!

public class Cha {

!

public void prepararReceita(){
ferverAgua();
misturarChaComAgua();
servirNaXicara();
adicionarLimao();
}
Utilizar variáveis
explicativas	

•
•

•

Contexto	


•

expressões complexas de se entender	


Solução	


•
•

extrair partes delas	

guardar resultados intermediários em variáveis
bem nomeadas	


Vantagem	


• código de melhor entendimento
def
	 	
	 	
	 	
end

calcular_total	
subtotal.mais(subtotal_taxavel.vezes(0.15)))	
.menos((subtotal().to_f  100.0)	
	 	 ? (subtotal().vezes(0.10)) : 0)
def calcular_total	
	 	 	
	 taxa = subtotal_taxavel().vezes(0.15)	
	 	 	
	 total = subtotal.mais(taxa)	
	 	 	
	 qualificado_ao_desconto = subtotal.to_f  100.0	
	 	 	
	 desconto = qualificadoAoDesconto	
	 	 	 	 	 	 	 ? subtotal.vezes(0.10)	
	 	 	 	 	 	 	 : Dinheiro.new(0.0)	
	 	 	
	 total.menos(desconto)	
}
•

Substituir construtor
por métodos fábrica	

Contexto	


•

existência de diversos construtores para criar
versões diferentes dos objetos	


•
•

•

pode haver confusão por falta de clareza de
intenção do construtor	


Solução	


•

criar métodos fábrica estáticos	


Vantagem	


• código de melhor entendimento
Como fazer
•

Execute um Extrair Método para isolar a lógica do
comportamento	


•
•

o método deve ser de classe	

repasse as dependências	


•
•

Se o método fábrica não estiver no objeto desejado, utilize o
Mover Método	


•
•

Teste	


Teste	


Remova o construtor original se não há chamadas a ele
Extrair Método
Mover Método
Outra maneira	

Java
public class Avaliacao {	
	 private int valor = 0;	
	 private String revisor = null;	
	 private String revista = null;	
!
	 public Avaliacao(int umaAvaliacao) {	
	 	 this(umaAvaliacao, Anonimo, );	
	 }	
!
	 public Avaliacao(int umaAvaliacao, String umRevisor) {	
	 	 this(umaAvaliacao, umRevisor, );	
	 }	
!
	 public Avaliacao(	
int umaAvaliacao, String umRevisor, String umaRevista) {	
	 	 valor = umaAvaliacao;	
	 	 revisor = umRevisor;	
	 	 revista = umaRevista;	
	 }	
	 // ...	
}
public static Avaliacao novaAvaliacaoAnonima(int valor) {	
	 return new Avaliacao(valor, Anonimo, );	
}	
!
public static Avaliacao novaAvaliacao(int valor, String revisor) {	
	 return new Avaliacao(valor, revisor, );	
}	
!
public static Avaliacao novaCritica(	
int valor, String revisor, String revista) {	
return new Avaliacao(valor, revisor, revista);	
}	
!
private Avaliacao(	
int umaAvaliacao, String umRevisor, String umaRevista) {	
valor = umaAvaliacao;	
revisor = umRevisor;	
revista = umaRevista;	
}
starWars.adicionarAvaliacao(new Avaliacao(2));	
starWars.adicionarAvaliacao(new Avaliacao(4, Joel Barbosa));	
starWars.adicionarAvaliacao(	
new Avaliacao(5, PH Santos, TechTudo));
starWars.adicionarAvaliacao(	
Avaliacao.novaAvaliacaoAnonima(2));	
!
starWars.adicionarAvaliacao(	
Avaliacao.novaAvaliacao(4, Joel Barbosa));	
!
starWars.adicionarAvaliacao(	
Avaliacao.novaCritica(5, PH Santos, TechTudo));
Substituir herança por
delegação	

•
•

Contexto	


•

uma subclasse utiliza apenas uma parte da
interface de sua superclasse e não reutiliza os
dados	


Solução	


•
•

crie um campo do tipo da superclasse	


•

remova a herança

refatore os métodos que utilizam o
comportamento da superclasse
Substituir números mágicos
por constantes ou enums	

•
•

•

Contexto	


•

valores literais no código que possuem um
significado	


Solução	


•

crie uma constante e nomeie-a com o seu
significado	


•

substitua os valores literais pelas constantes	


Vantagem	


• código de melhor entendimento
def energia_potencial(massa, altura) 	
	 	 massa * altura * 9.81	
end
CONSTANTE_GRAVITACIONAL = 9.81	
	 	
def energia_potencial(massa, altura) 	
	 	 massa * altura * CONSTANTE_GRAVITACIONAL 	
end
Resumo
• Um pouco de refatoração	

• o que é	

• técnicas específicas	

• alguns indicadores	

• Existe problema?	

• Deve-se refatorar em pequenos
incrementos
Bibliografia
• ASTELS, David. Test-Driven Development: A
Pratical Guide. Prentice Hall, 2003.	


• FOWLER, Martin; BECK, Kent; BRANT,

John; Opdyke, William; ROBERTS, Don.
Refactoring: Improving The Design of Existing
Code.	


• KERIEVSKY, Joshua. Refatoração Para

Padrões. Porto Alegre: Bookman, 2008.
Bibliografia
• ASTELS, David. Test-Driven Development: A
Pratical Guide. Prentice Hall, 2003.	


• FOWLER, Martin; BECK, Kent; BRANT,

John; Opdyke, William; ROBERTS, Don.
Refactoring: Improving The Design of Existing
Code.	


• KERIEVSKY, Joshua. Refatoração Para

Padrões. Porto Alegre: Bookman, 2008.

Más contenido relacionado

La actualidad más candente

Desenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com JunitDesenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com JunitAdolfo Neto
 
PHP 5.3 - Classes e Objetos
PHP 5.3 - Classes e ObjetosPHP 5.3 - Classes e Objetos
PHP 5.3 - Classes e ObjetosGeorge Mendonça
 
Orientação a Objetos com PHP
Orientação a Objetos com PHPOrientação a Objetos com PHP
Orientação a Objetos com PHPAugusto Pascutti
 
Uma Abordagem Prática de Orientação a Objetos com PHP (FLISOL DF 2011)
Uma Abordagem Prática de Orientação a Objetos com PHP (FLISOL DF 2011)Uma Abordagem Prática de Orientação a Objetos com PHP (FLISOL DF 2011)
Uma Abordagem Prática de Orientação a Objetos com PHP (FLISOL DF 2011)George Mendonça
 
Clean Code - Fork In Tuba
Clean Code - Fork In TubaClean Code - Fork In Tuba
Clean Code - Fork In TubaRafael Paz
 
Testes de Unidade com JUnit
Testes de Unidade com JUnitTestes de Unidade com JUnit
Testes de Unidade com JUnitelliando dias
 
TDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fislTDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fislAdriano Petrich
 
Treinamento Testes Unitários - parte 1
Treinamento Testes Unitários - parte 1Treinamento Testes Unitários - parte 1
Treinamento Testes Unitários - parte 1Diego Pacheco
 
Implementando Testes Unitários em Java - Manoel Pimentel
Implementando Testes Unitários em Java - Manoel PimentelImplementando Testes Unitários em Java - Manoel Pimentel
Implementando Testes Unitários em Java - Manoel PimentelManoel Pimentel Medeiros
 

La actualidad más candente (20)

Palestra Testes De Unidade Com JUnit
Palestra Testes De Unidade Com JUnitPalestra Testes De Unidade Com JUnit
Palestra Testes De Unidade Com JUnit
 
Desenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com JunitDesenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com Junit
 
JUnit
JUnitJUnit
JUnit
 
PHP 5.3 - Classes e Objetos
PHP 5.3 - Classes e ObjetosPHP 5.3 - Classes e Objetos
PHP 5.3 - Classes e Objetos
 
Code Smells
Code SmellsCode Smells
Code Smells
 
Orientação a Objetos com PHP
Orientação a Objetos com PHPOrientação a Objetos com PHP
Orientação a Objetos com PHP
 
Uma Abordagem Prática de Orientação a Objetos com PHP (FLISOL DF 2011)
Uma Abordagem Prática de Orientação a Objetos com PHP (FLISOL DF 2011)Uma Abordagem Prática de Orientação a Objetos com PHP (FLISOL DF 2011)
Uma Abordagem Prática de Orientação a Objetos com PHP (FLISOL DF 2011)
 
Testes Unitários
Testes UnitáriosTestes Unitários
Testes Unitários
 
Junit 4.0
Junit 4.0Junit 4.0
Junit 4.0
 
Clean Code - Fork In Tuba
Clean Code - Fork In TubaClean Code - Fork In Tuba
Clean Code - Fork In Tuba
 
TDD (Resumo)
TDD (Resumo)TDD (Resumo)
TDD (Resumo)
 
Testes de Unidade com JUnit
Testes de Unidade com JUnitTestes de Unidade com JUnit
Testes de Unidade com JUnit
 
Junit
JunitJunit
Junit
 
TDD Primeiro Contato
TDD Primeiro ContatoTDD Primeiro Contato
TDD Primeiro Contato
 
PHP Orientado a Objetos
PHP Orientado a ObjetosPHP Orientado a Objetos
PHP Orientado a Objetos
 
Clean code
Clean codeClean code
Clean code
 
TDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fislTDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fisl
 
Treinamento Testes Unitários - parte 1
Treinamento Testes Unitários - parte 1Treinamento Testes Unitários - parte 1
Treinamento Testes Unitários - parte 1
 
Implementando Testes Unitários em Java - Manoel Pimentel
Implementando Testes Unitários em Java - Manoel PimentelImplementando Testes Unitários em Java - Manoel Pimentel
Implementando Testes Unitários em Java - Manoel Pimentel
 
Java 12
Java 12Java 12
Java 12
 

Destacado

Abstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineAbstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineOtávio Calaça Xavier
 
Fundamentos de Java
Fundamentos de Java Fundamentos de Java
Fundamentos de Java jmosorio777
 
Conhecendo Java
Conhecendo JavaConhecendo Java
Conhecendo JavaTI Infnet
 
Web Semântica e bancos de dados NoSQL
Web Semântica e bancos de dados NoSQLWeb Semântica e bancos de dados NoSQL
Web Semântica e bancos de dados NoSQLOtávio Calaça Xavier
 
Fundamentos de java herbert schildt
Fundamentos de java   herbert schildtFundamentos de java   herbert schildt
Fundamentos de java herbert schildtRicardo Ramos
 
Introdução ao JPA com Hibernate
Introdução ao JPA com HibernateIntrodução ao JPA com Hibernate
Introdução ao JPA com HibernateDanilo Braga
 
Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Claudio Martins
 
Teste de Software - parte 1
Teste de Software - parte 1Teste de Software - parte 1
Teste de Software - parte 1Eduardo Mendes
 
Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Eduardo Mendes
 
TDD Projeto e Estrategias
TDD Projeto e EstrategiasTDD Projeto e Estrategias
TDD Projeto e EstrategiasEduardo Mendes
 
Evolucao de software - parte 2
Evolucao de software - parte 2Evolucao de software - parte 2
Evolucao de software - parte 2Eduardo Mendes
 
Desenvolvimento web com PHP parte 3
Desenvolvimento web com PHP parte 3Desenvolvimento web com PHP parte 3
Desenvolvimento web com PHP parte 3Eduardo Mendes
 
Evolucao de software - parte 1
Evolucao de software - parte 1Evolucao de software - parte 1
Evolucao de software - parte 1Eduardo Mendes
 

Destacado (20)

Adote OpenJDK
Adote OpenJDKAdote OpenJDK
Adote OpenJDK
 
GWT revista espirito
GWT revista espiritoGWT revista espirito
GWT revista espirito
 
Abstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineAbstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP Doctrine
 
Fundamentos de Java
Fundamentos de Java Fundamentos de Java
Fundamentos de Java
 
Conhecendo Java
Conhecendo JavaConhecendo Java
Conhecendo Java
 
Web Semântica e bancos de dados NoSQL
Web Semântica e bancos de dados NoSQLWeb Semântica e bancos de dados NoSQL
Web Semântica e bancos de dados NoSQL
 
Fundamentos de java herbert schildt
Fundamentos de java   herbert schildtFundamentos de java   herbert schildt
Fundamentos de java herbert schildt
 
Java - Aprenda rápido
Java - Aprenda rápidoJava - Aprenda rápido
Java - Aprenda rápido
 
Java para Leigos
Java para LeigosJava para Leigos
Java para Leigos
 
Introdução ao JPA com Hibernate
Introdução ao JPA com HibernateIntrodução ao JPA com Hibernate
Introdução ao JPA com Hibernate
 
Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7
 
Teste de Software - parte 1
Teste de Software - parte 1Teste de Software - parte 1
Teste de Software - parte 1
 
Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7
 
Html Aula 1 - parte 2
Html Aula 1 - parte 2Html Aula 1 - parte 2
Html Aula 1 - parte 2
 
RSpec com doubles
RSpec com doublesRSpec com doubles
RSpec com doubles
 
TDD Projeto e Estrategias
TDD Projeto e EstrategiasTDD Projeto e Estrategias
TDD Projeto e Estrategias
 
Evolucao de software - parte 2
Evolucao de software - parte 2Evolucao de software - parte 2
Evolucao de software - parte 2
 
Desenvolvimento web com PHP parte 3
Desenvolvimento web com PHP parte 3Desenvolvimento web com PHP parte 3
Desenvolvimento web com PHP parte 3
 
AngularJS - Rotas
AngularJS - RotasAngularJS - Rotas
AngularJS - Rotas
 
Evolucao de software - parte 1
Evolucao de software - parte 1Evolucao de software - parte 1
Evolucao de software - parte 1
 

Similar a Refatoração

Qualidade no desenvolvimento de Software com TDD e PHPUnit
Qualidade no desenvolvimento de Software com TDD e PHPUnitQualidade no desenvolvimento de Software com TDD e PHPUnit
Qualidade no desenvolvimento de Software com TDD e PHPUnitDomingos Teruel
 
Removendo o cheiro ruim do seu código - SoLiSC 2011
Removendo o cheiro ruim do seu código - SoLiSC 2011Removendo o cheiro ruim do seu código - SoLiSC 2011
Removendo o cheiro ruim do seu código - SoLiSC 2011Luís Cobucci
 
ZeroBugsProject - Técnicas de programação efetivas
ZeroBugsProject - Técnicas de programação efetivasZeroBugsProject - Técnicas de programação efetivas
ZeroBugsProject - Técnicas de programação efetivasRafael Chinelato Del Nero
 
Padrões de refatoração
Padrões de refatoraçãoPadrões de refatoração
Padrões de refatoraçãoThiago Pereira
 
TDD com Código Legado - "Atualizado"
TDD com Código Legado - "Atualizado"TDD com Código Legado - "Atualizado"
TDD com Código Legado - "Atualizado"Cesar Romero
 
Design Patterns on Rails
Design Patterns on RailsDesign Patterns on Rails
Design Patterns on Railstchandy
 
TDD com Código Legado
TDD com Código LegadoTDD com Código Legado
TDD com Código LegadoCesar Romero
 
Refactory Worshop
Refactory WorshopRefactory Worshop
Refactory Worshopguestd37c23
 
qualidade de código: boas práticas, princípios e padrões
qualidade de código: boas práticas, princípios e padrõesqualidade de código: boas práticas, princípios e padrões
qualidade de código: boas práticas, princípios e padrõesedgarddavidson.com
 
TDC 2015 São Paulo - Clean Code para Testers
TDC 2015 São Paulo - Clean Code para TestersTDC 2015 São Paulo - Clean Code para Testers
TDC 2015 São Paulo - Clean Code para TestersStefan Teixeira
 
TDD para "meros mortais"
TDD para "meros mortais"TDD para "meros mortais"
TDD para "meros mortais"thiagobapt
 
Clean code @rogeriofontes-techfriday-everis
Clean code @rogeriofontes-techfriday-everisClean code @rogeriofontes-techfriday-everis
Clean code @rogeriofontes-techfriday-everisRogerio Fontes
 
Slide Aula - Curso CakePHP
Slide Aula - Curso CakePHPSlide Aula - Curso CakePHP
Slide Aula - Curso CakePHPRangel Javier
 
Voce se preocupa com performance ou é sempre problema da infra
Voce se preocupa com performance ou é sempre problema da infraVoce se preocupa com performance ou é sempre problema da infra
Voce se preocupa com performance ou é sempre problema da infraCDS
 

Similar a Refatoração (20)

Qualidade no desenvolvimento de Software com TDD e PHPUnit
Qualidade no desenvolvimento de Software com TDD e PHPUnitQualidade no desenvolvimento de Software com TDD e PHPUnit
Qualidade no desenvolvimento de Software com TDD e PHPUnit
 
Removendo o cheiro ruim do seu código - SoLiSC 2011
Removendo o cheiro ruim do seu código - SoLiSC 2011Removendo o cheiro ruim do seu código - SoLiSC 2011
Removendo o cheiro ruim do seu código - SoLiSC 2011
 
ZeroBugsProject - Técnicas de programação efetivas
ZeroBugsProject - Técnicas de programação efetivasZeroBugsProject - Técnicas de programação efetivas
ZeroBugsProject - Técnicas de programação efetivas
 
Padrões de refatoração
Padrões de refatoraçãoPadrões de refatoração
Padrões de refatoração
 
TDD com Código Legado - "Atualizado"
TDD com Código Legado - "Atualizado"TDD com Código Legado - "Atualizado"
TDD com Código Legado - "Atualizado"
 
Design Patterns on Rails
Design Patterns on RailsDesign Patterns on Rails
Design Patterns on Rails
 
TDD com Código Legado
TDD com Código LegadoTDD com Código Legado
TDD com Código Legado
 
PHPZEIRO: Adote um framework
PHPZEIRO: Adote um frameworkPHPZEIRO: Adote um framework
PHPZEIRO: Adote um framework
 
Introdução ao TDD
Introdução ao TDDIntrodução ao TDD
Introdução ao TDD
 
Clean code em C#
Clean code em C#Clean code em C#
Clean code em C#
 
Refatoração de Código Legado
Refatoração de Código LegadoRefatoração de Código Legado
Refatoração de Código Legado
 
TDD na Prática
TDD na PráticaTDD na Prática
TDD na Prática
 
Refactory Worshop
Refactory WorshopRefactory Worshop
Refactory Worshop
 
qualidade de código: boas práticas, princípios e padrões
qualidade de código: boas práticas, princípios e padrõesqualidade de código: boas práticas, princípios e padrões
qualidade de código: boas práticas, princípios e padrões
 
Django Básico
Django BásicoDjango Básico
Django Básico
 
TDC 2015 São Paulo - Clean Code para Testers
TDC 2015 São Paulo - Clean Code para TestersTDC 2015 São Paulo - Clean Code para Testers
TDC 2015 São Paulo - Clean Code para Testers
 
TDD para "meros mortais"
TDD para "meros mortais"TDD para "meros mortais"
TDD para "meros mortais"
 
Clean code @rogeriofontes-techfriday-everis
Clean code @rogeriofontes-techfriday-everisClean code @rogeriofontes-techfriday-everis
Clean code @rogeriofontes-techfriday-everis
 
Slide Aula - Curso CakePHP
Slide Aula - Curso CakePHPSlide Aula - Curso CakePHP
Slide Aula - Curso CakePHP
 
Voce se preocupa com performance ou é sempre problema da infra
Voce se preocupa com performance ou é sempre problema da infraVoce se preocupa com performance ou é sempre problema da infra
Voce se preocupa com performance ou é sempre problema da infra
 

Más de Eduardo Mendes

JavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosJavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosEduardo Mendes
 
Angular JS - Fundamentos
Angular JS - FundamentosAngular JS - Fundamentos
Angular JS - FundamentosEduardo Mendes
 
Singleton - Padrão de Projeto
Singleton - Padrão de ProjetoSingleton - Padrão de Projeto
Singleton - Padrão de ProjetoEduardo Mendes
 
Introdução à Internet, Http e HTML
Introdução à Internet, Http e HTMLIntrodução à Internet, Http e HTML
Introdução à Internet, Http e HTMLEduardo Mendes
 
Estimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEstimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEduardo Mendes
 
Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Eduardo Mendes
 
Validações no Ruby on Rails
Validações no Ruby on Rails Validações no Ruby on Rails
Validações no Ruby on Rails Eduardo Mendes
 
Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Eduardo Mendes
 

Más de Eduardo Mendes (20)

JavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosJavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a Objetos
 
Angular JS - Fundamentos
Angular JS - FundamentosAngular JS - Fundamentos
Angular JS - Fundamentos
 
Singleton - Padrão de Projeto
Singleton - Padrão de ProjetoSingleton - Padrão de Projeto
Singleton - Padrão de Projeto
 
Layout Fluido
Layout FluidoLayout Fluido
Layout Fluido
 
Web Design Responsivo
Web Design ResponsivoWeb Design Responsivo
Web Design Responsivo
 
Html - Aula 4
Html - Aula 4Html - Aula 4
Html - Aula 4
 
Html - Aula 3
Html - Aula 3Html - Aula 3
Html - Aula 3
 
Introdução à Internet, Http e HTML
Introdução à Internet, Http e HTMLIntrodução à Internet, Http e HTML
Introdução à Internet, Http e HTML
 
ExtJS-4
ExtJS-4ExtJS-4
ExtJS-4
 
Jquery 2
Jquery 2Jquery 2
Jquery 2
 
Jquery
JqueryJquery
Jquery
 
Estimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEstimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de Software
 
Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2
 
Validações no Ruby on Rails
Validações no Ruby on Rails Validações no Ruby on Rails
Validações no Ruby on Rails
 
Padrão Iterator
Padrão IteratorPadrão Iterator
Padrão Iterator
 
Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)
 
Padrão Command
Padrão CommandPadrão Command
Padrão Command
 
Padrão Fachada
Padrão FachadaPadrão Fachada
Padrão Fachada
 
Padrão Adapter
Padrão AdapterPadrão Adapter
Padrão Adapter
 
Web Design Responsivo
Web Design ResponsivoWeb Design Responsivo
Web Design Responsivo
 

Refatoração

  • 2. Agenda • Refatoração • Exemplos • Técnicas de Refatoração 2
  • 4. O que é? • “É o processo de realizar mudanças em código existente e funcional sem alterar seu comportamento” ! • Alterar COMO o código • NÃO alterar O QUE ele faz ! • Aprimorar a estrutura interna
  • 5. Qual a relação com TDD?
  • 6. Refatoração e TDD • Após implementar o código mais simples para fazer o teste passar • refatoramos o código para remover as duplicações que adicionamos para ver o teste passar • Como temos um conjunto seguro de testes, • então podemos refatorar com confiança
  • 7. O que nos motiva a refatorar?
  • 8. Motivação • facilitar a adição de código novo • melhorar o projeto existente • obter um melhor entendimento de código • tornar a programação menos irritante
  • 10. Contextos • quando existe duplicação de código • quando a intenção é obscura • percebemos que o código e/ou sua intenção não são claros • ex: lógica condicional complicada • quando detectamos problemas de código (“bad smells”) • ou indícios de problemas
  • 11. Duplicação • Falência de um bom código • Existem várias formas • simples e óbvios • índícios • disfarçados
  • 12. Say Everything Once and Only Once ! Don’t Repeat Yourself
  • 13. Diga tudo uma vez e apenas uma vez ! Não se repita
  • 16. def save if (arquivo.nil?) return false end diretorio = Diretorio.new(arquivo) diretorio.add(arquivo) diretorio.close() return true end def saveAs arquivo = view.file if (arquivo.nil?) return false end diretorio = Diretorio.new(arquivo) diretorio.add(arquivo) diretorio.close() return true end
  • 17. def save if (arquivo.nil?) { return false } diretorio = Diretorio.new(arquivo) diretorio.add(arquivo) diretorio.close() return true end def saveAs arquivo = view.file save end
  • 19. class MovieList def initialize @movies = [] @number_of_movies = 0 end def size @movies.size end def add movie_to_add @movies movie_to_add @number_of_movies = @number_of_movies + 1 end end
  • 20. class MovieList ! def initialize @movies = [] @number_of_movies = 0 end ! def size @movies.size end def add movie_to_add @movies movie_to_add end ! end
  • 22. O que torna um código claro? • Escolher bons nomes • dicionário na mão para ajudar a comunicar nossa intenção • TDD • Como escrevemos 1º o teste, somos forçados a pensar na interface do código antes da sua implementação • oportunidade de pensar a partir do ponto de vista do usuário da classe
  • 24. Bad Smells • • • • Excesso de comentários Classes de dados Código duplicado Intimidade inapropriada ! ! ! • • • • Classes muito grandes Classes “preguiçosas” Métodos longos Switches
  • 25. Excesso de comentários def init // set the layout content_pane.layout(FlowLayout.new) ! // create the list movie_list = List.new(my_editor.movies) scroller = ScrollPane.new(movie_list) content_pane.add(scroller) ! // create the field movie_field = TextField.new(16) content_pane.add(movie_field) ! // create theadd button add_button = Button.new(“Add) .... end
  • 26. Classes de dados class Ponto attr_accessor :x, :y def initialize(x = 0, y = 0) @x = x; @y = y; end end
  • 27. Com intimidade def temperatura t = estacao.termometro t.temperatura end
  • 29. Classes muito grandes • Desproporcional às outras • Por quê? • tenta fazer muita coisa? • possui muito código condicional? • possui muito comportamento condicional? • Como identificar?
  • 30. Classes “preguiçosas” • Classes tão pequentas que não justificam sua existência • Devem ser fundidas à outras classes
  • 31. Switches class Empregado // 0 - engenheiro, 1 - vendedor, 2 - gerente attr_accessor :tipo_empregado ! def nome_do_departamento case @tipo_empregado when 0 return Engenheiro when 1 return Vendedor when 2 return Gerente else return Desconhecido end end end
  • 32. Dica • Princípios de Orientação a objetos • Design Patterns
  • 34. Como refatorar 1. Estrutura de testes que proporcionem feedback 2. Pequenos passos 3. IDEs
  • 36. Refatorações • • • • • Extrair classe Extrair interface Extrair método Substituir código digitado por subclasses ou objeto de valor Substituir condicional por polimorfismo • Utilizar métodos gabaritos • Utilizar variavel explicativa • Substituir construtores por métodos fábrica • Substituir herança por delegação • Substituir números mágicos por constantes
  • 37. Extrair Classe • Contexto • classes muito grandes • comportamento disperso • Solução • fracionar as classes em pedaços menores mais coesos • Extração de comportamentos para uma nova classe
  • 38. class MovieListWriter attr_accessor :destination ! def initialize(aWriter = nil) destination = aWriter; end ! def write_movie_list(a_list) a_list.movies.each do |movie| write_movie(movie) end end ! def write_movie(a_movie) destination.write(a_movie.name) destination.write('|') destination.write(a_movie.category.to_s) destination.write('|') begin destination.write(a_movie.rating.to_s) rescue UnratedException = ex destination.write(-1) end destination.write('n') end end
  • 39. class Movie // ... def write_to(destination)
 destination.write(name) destination.write('|') destination.write(category.to_s) destination.write('|') begin destination.write(rating.to_s) rescue UnratedException = ex destination.write(-1) end destination.write('n'); end // ... end
  • 40. class MovieList write_to(destination)
 movies.each do |movie| movie.write_to(destination) end end end
  • 41. Extrair Interface • Contexto • Se quer abstrair a forma de uma implementação concreta • Comportamentos importantes substituíveis ou reversíveis • Solução • criar interfaces para poder substituir o concreto tardiamente
  • 42. public class MovieList { private CollectionMovie movies = new ArrayListMovie(); ! } public int size() { return movies.size(); } public void add(Movie movieToAdd) { movies.add(movieToAdd); }
  • 43. public interface IMovieList { ! public abstract int size(); ! public abstract void add(Movie movie); ! }
  • 44. public class MovieList
 implements IMovieList { //... }
  • 46. Extrair Método • Contexto • métodos muito longos • lógicas de complexo entendimento • Solução • fracionar o método em métodos menores mais coesos • Extração de comportamentos para novos métodos
  • 47. public void init() { } getContentPane().setLayout(new FlowLayout()); movieList = new JList(myEditor.getMovies()); JScrollPane scroller = new JScrollPane(movieList); getContentPane().add(scroller); movieField = new JTextField(16); getContentPane().add(movieField); addButton = new JButton(Add); ....
  • 48. public void init() { // set the layout getContentPane().setLayout(new FlowLayout()); ! // create the list movieList = new JList(myEditor.getMovies()); JScrollPane scroller = new JScrollPane(movieList); getContentPane().add(scroller); ! // create the field movieField = new JTextField(16); getContentPane().add(movieField); ! // create theadd button addButton = new JButton(Add); .... }
  • 49. public void init() { setLayout(); initMovieList(); initMovieField(); initAddButton(); } private void setLayout() { getContentPane().setLayout(new FlowLayout()); } private void initMovieList() { movieList = new JList(getMovies()); JScrollPane scroller = new JScrollPane(movieList); getContentPane().add(scroller); } private void initMovieField() { movieField = new JTextField(16); getContentPane().add(movieField); } private void initAddButton() {...
  • 50. Extrair Método 2 • Se um trecho de código duplicado diferentes do programa Classe1
  • 51. Extrair Método 2 • Se as duplicatas de código devem permanecer sempre iguais, ou seja, uma vez que se realize uma alteração em uma delas, as demais devem refletir a alteração Classe1
  • 52. public void doGet(HttpservletRequest request, HttpServletResponse response) throws ServletException, IOException{ String p = request.getParameter(“personagem”); request.setAttribute(“personagem”, p); //Mais código } ! public void doPost(HttpservletRequest request, HttpServletResponse response) throws ServletException, IOException{ String p = request.getParameter(“personagem”); request.setAttribute(“personagem”, p); //Mais código }
  • 53. • Extraindo o método Concentre o código que se repete em um único lugar, por exemplo, em um método e leve as dependências para lá public void doGet(HtttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ String p = request.getParameter(“personagem”); request.setAttribute(“personagem”, p); //Mais código } public void novoMetodo(HtttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ String p = request.getParameter(“personagem”); request.setAttribute(“personagem”, p); //Mais código }
  • 54. public void novoMetodo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ ..... } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ novoMetodo(request, response); } ! public void doPost(HttpservletRequest request, HttpServletResponse response) throws ServletException, IOException{ novoMetodo(request, response); }
  • 55. Refatorações • • • • • Extrair classe Extrair interface Extrair método Substituir código digitado por subclasses ou objetos de valor Substituir condicional por polimorfismo • Utilizar métodos gabaritos • Utilizar variavel explicativa • Substituir construtores por métodos fábrica • Substituir herança por delegação • Substituir números mágicos por constantes
  • 56. Substituir código digitado por subclasses • Contexto • classes indicam subtipos através de código digitado • Solução • Criar uma subclasse para cada alternativa • Vantagem • Evitam-se complexos condicionais
  • 57. class Empregado //0 - engenheiro, 1 - vendedor, 2 - gerente attr_accessor :tipo_do_empregado //.. end
  • 58. class Empregado // ... end ! class Engenheiro Empregado // ... end ! class Vendedor Empregado // ... end ! class Gerente Empregado // ... end
  • 59.
  • 60. Substituir condicional por polimorfismo • Contexto • classes indicam subtipos através de código digitado • Solução • Criar uma subclasse para cada alternativa • Vantagem • Evitam-se complexos condicionais
  • 61. public class Empregado // 0 - engenheiro, 1 - vendedor, 2 - gerente attr_accessor :tipo_do_empregado ! def nome_do_departamento case @tipoDoEmpregado when 0 return Engenharia when 1 return Vendas when 2 return Gerência else return Desconhecido end end end
  • 62. class Empregado def nome_do_departamento end end ! class Engenheiro Empregado def nome_do_departamento Engenharia end end ! class Vendedor Empregado def nome_do_departamento Vendas end end ! class Gerente extends Empregado def nome_do_departamento Gerência end end
  • 63. Utilizar métodos gabaritos • • Contexto • métodos em subclasses executam passos similares na mesma ordem • os passos são diferentes Solução • extraia os passos para métodos com mesma assinatura • • crie um método gabarito final na superclasse especialize os métodos nas subclasses
  • 64. Contexto public class Cafe { public void prepararReceita(){ ferverAgua(); misturarCafeComAgua(); servirNaXicara(); adicionarAcucarELeite(); } ! ! ! ! ! public class Cha { ! public void prepararReceita(){ ferverAgua(); misturarChaComAgua(); servirNaXicara(); adicionarLimao(); }
  • 65.
  • 66. Utilizar variáveis explicativas • • • Contexto • expressões complexas de se entender Solução • • extrair partes delas guardar resultados intermediários em variáveis bem nomeadas Vantagem • código de melhor entendimento
  • 67. def end calcular_total subtotal.mais(subtotal_taxavel.vezes(0.15))) .menos((subtotal().to_f 100.0) ? (subtotal().vezes(0.10)) : 0)
  • 68. def calcular_total taxa = subtotal_taxavel().vezes(0.15) total = subtotal.mais(taxa) qualificado_ao_desconto = subtotal.to_f 100.0 desconto = qualificadoAoDesconto ? subtotal.vezes(0.10) : Dinheiro.new(0.0) total.menos(desconto) }
  • 69. • Substituir construtor por métodos fábrica Contexto • existência de diversos construtores para criar versões diferentes dos objetos • • • pode haver confusão por falta de clareza de intenção do construtor Solução • criar métodos fábrica estáticos Vantagem • código de melhor entendimento
  • 70.
  • 71. Como fazer • Execute um Extrair Método para isolar a lógica do comportamento • • o método deve ser de classe repasse as dependências • • Se o método fábrica não estiver no objeto desejado, utilize o Mover Método • • Teste Teste Remova o construtor original se não há chamadas a ele
  • 73.
  • 74.
  • 76.
  • 78. public class Avaliacao { private int valor = 0; private String revisor = null; private String revista = null; ! public Avaliacao(int umaAvaliacao) { this(umaAvaliacao, Anonimo, ); } ! public Avaliacao(int umaAvaliacao, String umRevisor) { this(umaAvaliacao, umRevisor, ); } ! public Avaliacao( int umaAvaliacao, String umRevisor, String umaRevista) { valor = umaAvaliacao; revisor = umRevisor; revista = umaRevista; } // ... }
  • 79. public static Avaliacao novaAvaliacaoAnonima(int valor) { return new Avaliacao(valor, Anonimo, ); } ! public static Avaliacao novaAvaliacao(int valor, String revisor) { return new Avaliacao(valor, revisor, ); } ! public static Avaliacao novaCritica( int valor, String revisor, String revista) { return new Avaliacao(valor, revisor, revista); } ! private Avaliacao( int umaAvaliacao, String umRevisor, String umaRevista) { valor = umaAvaliacao; revisor = umRevisor; revista = umaRevista; }
  • 80. starWars.adicionarAvaliacao(new Avaliacao(2)); starWars.adicionarAvaliacao(new Avaliacao(4, Joel Barbosa)); starWars.adicionarAvaliacao( new Avaliacao(5, PH Santos, TechTudo));
  • 82. Substituir herança por delegação • • Contexto • uma subclasse utiliza apenas uma parte da interface de sua superclasse e não reutiliza os dados Solução • • crie um campo do tipo da superclasse • remova a herança refatore os métodos que utilizam o comportamento da superclasse
  • 83.
  • 84.
  • 85. Substituir números mágicos por constantes ou enums • • • Contexto • valores literais no código que possuem um significado Solução • crie uma constante e nomeie-a com o seu significado • substitua os valores literais pelas constantes Vantagem • código de melhor entendimento
  • 86. def energia_potencial(massa, altura) massa * altura * 9.81 end
  • 87. CONSTANTE_GRAVITACIONAL = 9.81 def energia_potencial(massa, altura) massa * altura * CONSTANTE_GRAVITACIONAL end
  • 88. Resumo • Um pouco de refatoração • o que é • técnicas específicas • alguns indicadores • Existe problema? • Deve-se refatorar em pequenos incrementos
  • 89. Bibliografia • ASTELS, David. Test-Driven Development: A Pratical Guide. Prentice Hall, 2003. • FOWLER, Martin; BECK, Kent; BRANT, John; Opdyke, William; ROBERTS, Don. Refactoring: Improving The Design of Existing Code. • KERIEVSKY, Joshua. Refatoração Para Padrões. Porto Alegre: Bookman, 2008.
  • 90.
  • 91. Bibliografia • ASTELS, David. Test-Driven Development: A Pratical Guide. Prentice Hall, 2003. • FOWLER, Martin; BECK, Kent; BRANT, John; Opdyke, William; ROBERTS, Don. Refactoring: Improving The Design of Existing Code. • KERIEVSKY, Joshua. Refatoração Para Padrões. Porto Alegre: Bookman, 2008.

Notas del editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n