REFACTORING - BAD SMELLS
DISEO 2013
Paola Saavedra Martnez
2
Practicas Refactoring
DISEO 2013
Extract Method
Se tiene un fragmento de cdigo que se puede agrupar junto.
Transformar el fragmento en un mtodo cuyo nombre explica el propsito del mtodo.
Es una de las refactorizaciones ms comunes.
Se debe mirar un mtodo que es demasiado largo o mirar el cdigo que necesita un comentario para entender su propsito.
3 DISEO 2013
Extract Method void printOwing(double amount) { printBanner(); //print details System.out.println ("name:" + _name); System.out.println ("amount" + amount); } void printOwing(double amount) { printBanner(); printDetails(amount); } void printDetails (double amount) { System.out.println ("name:" + _name); System.out.println ("amount" + amount); }
Practicas Refactoring
4
Practicas Refactoring
DISEO 2013
Pull Up Field
Dos subclases tienen el mismo campo.
Mover el campo de la superclase
La nica manera de determinar lo que est pasando es mirar a los campos y ver la forma en que son utilizados por otros mtodos.
Si se estn utilizando de una manera similar, se puede generalizar.
Se elimina la declaracin de datos duplicados.
5
Practicas Refactoring
DISEO 2013
Pull Up Field
6
Practicas Refactoring
DISEO 2013
Introduce Parameter Object
Grupo de parmetros que tienen que pasar juntos.
Varios mtodos pueden utilizar este grupo en una o varias clases
Convertir estos parmetros en objetos para agrupar los datos en conjunto
Reduce el tamao de las listas de parmetros que suelen ser difciles de entender
7
Practicas Refactoring
DISEO 2013
Introduce Parameter Object
class DateRange {
DateRange (Date start, Date end)
{
_start = start;
_end = end;
}
Date getStart() {
return _start;
}
Date getEnd() {
return _end;
}
private final Date _start;
private final Date _end;
}
8
Practicas Refactoring
DISEO 2013
Move Method
Un mtodo ser utilizado por ms caractersticas de otra clase que la propia clase
Cuando las clases tienen demasiadas responsabilidades o cuando las clases estn colaborando mucho (altamente acopladas)
Se generan clases mas simples
Mtodo candidato: ver el objeto con el cual tiene mas interaccin
9
Practicas Refactoring
DISEO 2013
Move Method
10
Practicas Refactoring
DISEO 2013
Move Field
Un campo ser utilizado por otra clase ms de la clase en la que est definida
Cuando los mtodos de otra clase utilizan el campo ms que la propia clase
Si es razonable la ubicacin del mtodo donde: mover el campo.
11
Practicas Refactoring
DISEO 2013
Move Field
12
Practicas Refactoring
DISEO 2013
Extract Class
Hay una clase haciendo un trabajo que debe ser realizado por dos
Crear una clase nueva y mover los campos y mtodos pertinentes a la nueva clase
Una clase es demasiado grande para entender fcilmente.
13
Practicas Refactoring
DISEO 2013
Extract Class
14
Practicas Refactoring
DISEO 2013
Substitut Algorithm
Se desea reemplazar un algoritmo con otro mas claro.
Reemplazar el cuerpo del mtodo con el nuevo algoritmo
Cuando se quiere que el algoritmo haga algo un poco diferente: primero sustituir
15
Practicas Refactoring
DISEO 2013
Substitut Algorithm
String foundPerson(String[] people)
{
for (int i = 0; i < people.length; i++) {
if (people[i].equals ("Don")){return "Don";}
if (people[i].equals ("John")){return "John";}
if (people[i].equals ("Kent")){return "Kent";}}
return "";
}
16
Practicas Refactoring
DISEO 2013
Substitut Algorithm
String foundPerson(String[] people)
{
List candidates = Arrays.asList(new String[] {"Don", "John",
"Kent"});
for (int i=0; i
17
Practicas Refactoring
DISEO 2013
Replace Parameter with Method
Largas listas de parmetros son difciles de entender y se deben reducir lo mximo posible.
Una forma es ver si el mtodo de recepcin utiliza los parmetros: eliminar el parmetro haciendo el clculo en su propio mtodo.
No se puede quitar el parmetro:
Si el clculo se basa en un parmetro del mtodo de llamada, ya que el parmetro puede cambiar con cada llamada
Si el receptor no tiene una referencia al remitente
Quitar el parmetro y dejar que el receptor llame al mtodo
18
Practicas Refactoring
DISEO 2013
Replace Parameter with Method
int basePrice = _quantity * _itemPrice;
discountLevel = getDiscountLevel();
double finalPrice = discountedPrice (basePrice, discountLevel);
int basePrice = _quantity * _itemPrice;
double finalPrice = discountedPrice (basePrice);
19
Practicas Refactoring
DISEO 2013
Replace Data Value with Object
Se tiene un dato que necesita otros datos o un
comportamiento adicional
Puede aceptarse en las primeras etapas de diseo
Transformar el dato en un objeto
20
Practicas Refactoring
DISEO 2013
Replace Type Code with State/Strategy
Se tiene un cdigo que afecta el comportamiento de una
clase pero no se puede utilizar subclases.
Utiliza el patrn State o Strategy
Reemplazar el cdigo por un objeto
21
Bad Smells
DISEO 2013
Duplicated Code
Misma estructura de cdigo en mas de un lugar
En dos mtodos de la misma clase Extract Method
En dos subclases hermanas Extract Method
Pull Up Field
22
Bad Smells
DISEO 2013
Duplicated Code
Clases no relacionadas Extract Class
En una clase y luego utilizar el nuevo componente en la otra
Opciones El mtodo realmente pertenece slo a una de las clases y
debe ser invocada por la otra clase
El mtodo pertenece en una tercera clase que debe ser mencionada por tanto de las clases originales.
23
Bad Smells
DISEO 2013
Large Class
Cuando una clase est tratando de hacer demasiado aparece con demasiadas variables de instancia.
Cuando una clase tiene demasiadas variables de instancia el cdigo duplicado no puede estar muy lejos.
Extract Class
Extract SubClass
24
Bad Smells
DISEO 2013
Long Parameter List
Programacin tradicional: pasar por parametro todo lo que necesita una rutina
Objetos: siempre se le puede pedir a otro objeto lo que necesita.
Practicas refactoring
Replace Parameter whit Method
Introduce Parameter Object
25
Bad Smells
DISEO 2013
Divergent Change
Se estructura el sw para hacer el cambio ms facil
Cuando se debe cambiar una clase (mtodos) de diferentes maneras por diferentes razones.
Es probable que dos objetos sean mejor que uno
Practicas refactoring Extract Class
26
Bad Smells
DISEO 2013
Data Class
Clases que tienen campos y mtodos getting y setting .
Son punto de partida pero deben tomar alguna responsabilidad
Practicas refactoring Move Method
Extract Method
27
Bad Smells
DISEO 2013
Obsession primitive
Se utilizan tipos primitivos como Strings o Doubles o Ints para representar conceptos que realmente merecen ser representados por clases de objetos
Para modelar estructura de una clase Referenciar a otra clase Utilizar un tipo primitivo
Practicas refactoring Replace Data Value with object Replace Type Code with State/Strategy
Resistencia a crear clase
porque en ese momento solo
sirve para encapsular un
simple entero o un string con
poco comportamiento
28
Bad Smells
DISEO 2013
Comment
Primero eliminar bad smell: se puede descubrir que ahora los comentarios son superfluos.
Practicas refactoring Si se necesita un comentario para explicar lo que
hace un bloque de cdigo: Extract Method
Si todavia necesita un comentario para explicar lo que hace: Rename Method
29
Bibliografia
Obligatoria
Refactoring: Improving the Design of Existing Code. Martin Fowler, Kent Beck, John Brant y William Opdyke, Addison-Wesley 1999
DISEO 2013