pongo en negrita las que me han parecido mas interesantes o despertado algún otro interés.
http://avdi.org/devblog/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/
http://misko.hevery.com/2008/07/18/breaking-the-law-of-demeter-is-like-looking-for-a-needle-in-the-haystack/
http://www.dan-manges.com/blog/37
http://www.dan-manges.com/blog/37de la pagina 6 en adelante
http://avdi.org/devblog/2011/06/28/do-or-do-not-there-is-no-try/
http://pragprog.com/articles/tell-dont-ask
miércoles, 10 de agosto de 2011
martes, 9 de agosto de 2011
links que voy mirando
http://codeofdoom.com/wordpress/2009/03/29/rebuilding-vs-refactoring/
http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html
http://theknowledge.me.uk/mywiki/books/refactoring-improving-the-design-of-existing-code.html#Chapter_10_Making_Method_Calls_Better
http://www.javaworld.com/javaworld/javaqa/2001-04/03-qa-0420-abstract.htm
http://codeofdoom.com/wordpress/2009/02/12/learn-this-when-to-use-an-abstract-class-and-an-interface/
http://codeofdoom.com/wordpress/2009/02/04/the-importance-of-composition/
http://geekswithblogs.net/mahesh/archive/2006/07/05/84120.aspx
http://en.wikipedia.org/wiki/Law_of_Demeter
http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx
http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake
http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html
http://theknowledge.me.uk/mywiki/books/refactoring-improving-the-design-of-existing-code.html#Chapter_10_Making_Method_Calls_Better
http://www.javaworld.com/javaworld/javaqa/2001-04/03-qa-0420-abstract.htm
http://codeofdoom.com/wordpress/2009/02/12/learn-this-when-to-use-an-abstract-class-and-an-interface/
http://codeofdoom.com/wordpress/2009/02/04/the-importance-of-composition/
http://geekswithblogs.net/mahesh/archive/2006/07/05/84120.aspx
http://en.wikipedia.org/wiki/Law_of_Demeter
http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx
http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake
domingo, 7 de agosto de 2011
flash cards refactoring
Aquí tengo subidas unas cuantas flashcards para ayudar a prenderme todos los refactorings que hay y las familias a las que pertenecen, así como códigos de ejemplo para aprender a identificar el refactoring que hay que hacer.
flashcards sobre refactoring
flashcards sobre refactoring
sábado, 6 de agosto de 2011
Replace Parameter with Method
el proceso entero con comentarios se puede seguir mediante el archivo de MoonEdit (programa muy chulo , gratis y sin peso apenas) replace parameter with method
CODIGO INICIAL
public double getPrice(){ int basePrice = _quantity * _itemPrice; int discountLevel; if (_quantity > 300) discountLevel = 3; else if (_quantity > 200) discountLevel = 2; else discountLevel = 1; double finalPrice = discountedPrice (basePrice, discountLevel); return finalPrice; }
private double discountedPrice (int basePrice, int discountLevel) { if (discountLevel == 2) return basePrice * 0.1; elseif (discountLevel == 3) return basePrice * 0.2; else return basePrice * 0.05; }CODIGO FINAL
public double getPrice() { if (Discount.isEnoughQuantityForPlatinum(_quantity)) return getBasePrice() * Discount.PLATINUM.getPercentage(); elseif (Discount.isEnoughQuantityForPlus(_quantity)) return getBasePrice() * Discount.PLUS.getPercentage(); else return getBasePrice() * Discount.NORMAL.getPercentage(); } private int getBasePrice() { return _quantity * _itemPrice; } class Discount{ static final int MIN_QUANTITY_FOR_PLATINUM = 300; static final int MIN_QUANTITY_FOR_PLUS = 200;
static final int PLATUNUM_LEVEL = 3; static final int PLUS_LEVEL = 2; static final int NORMAL_LEVEL = 1; static final float PLATINUM__PERCENTAGE = 0.2; static final float PLUS__PERCENTAGE = 0.1; static final float NORMAL_PERCENTAGE = 0,05; public static final Discount NORMAL = new Discount (NORMAL_LEVEL , NORMAL_PERCENTAGE); public static final Discount PLUS = new Discount (PLUS_LEVEL , PLUS_PERCENTAGE); public static final Discount PLATINUM = new Discount (PLATINUM_LEVEL , PLATINUM_PERCENTAGE); private final int _level; private final float _percentage;
private Discount(int level,float percentage) { _level = level; _percentage = percentage; } public getLevel() { return _level; } public getPercentage() { return _percentage; } public boolean isEnoughQuantityForPlus(quantity) { if (quantity > MIN_QUANTITY_FOR_PLUS) return true; return false; } public boolean isEnoughQuantityForPlatinum(quantity) { if (quantity > MIN_QUANTITY_FOR_PLATINUM) return true; return false; } bad Smell: getPrice() -- long method , finalPrice variable is always the discount Calculated Price
refactoring used :
replace parameter with method <- making methods calls simpler
invented name refactor (i don´t know if its a current name for this)
introduce multible return points <- simplifying Conditional Expressions
inline method <- componsing methods
replace Magic Number with Symbolic constant <- organizing data
replace type code with class <- organizing data
move method <- move features between objects
consolidate conditional expression <- simplifying conditional expressions
jueves, 4 de agosto de 2011
Preserve Whole Object exception
He tratado de realizar variaciones sobre la posibilidad que se apunta en "sourcemaking.com":
[motivation] "Passing in the required object causes a dependency between the required object and the called object. If this going to mess up your dependency structure, don't use Preserve Whole Object".
Como excepción a la aplicación de preserve whole object<-making methods caller sympler.
para ello he usado un código inventado por mi a bote pronto, sobre la gestión de una película y la contabilidad de sus gastos quedando el código de la forma siguiente:
se puede descargar el archivo de moonEdit para ver como he llegado a ese código y consideraciones preserver whole object exception
class peliculaDeMiedo{main Camara camara = new Camara(4);integer Plano = 6;integer escena = 8;integer litrosSangre= 44;String [] actores = [hulbrainer -> datosHulbrainer, kevincosnerjose ->datosKevincosnerjose, avaganer->datosAvaganer];Vampiro dragucula = new Vampiro(camara,plano,escena,actores[hulbrainer]);......ElementosPelicula elementosUsados = new ElementosPeliculaMiedo(camara,plano,escena,litrosSangre);Double pagaDia = new ContableMiedo().dameLaPagaStaff(elementosUsados);}
class ElementosPeliculaclass ElementosPeliculaAmor extends ElementosPeliculaclass ElementosPeliculaMiedo extends ElementosPelicula
class Camara{ Camara(integer camara) { un monton de peticiones a otros metodos, consultas a servicios y logaritmos nepericonianos; this.ordenDeLaCamara=camara; } Double calculaCosteAnual() { un monton de calculos y de historias que miran el precio de la camara , depreciacion , duracion de la lampara y lo que te de la gana }}
class VampiroVampiro (Camara CamaraEnfocada, integer PlanoPelicula, integer escena,Actor actor){ sus cosas}
class Contable{ Contable(){ se hacer cositas con los números}public Double damePagaStaff (elementosPelicula elementos){ Double consteCamara = elementos.camara.calcilaCosteAnual()/365; double gastoExtraPelicula = calculaGastoProducto(elementos); etc etc.... return unapasta;}private abstract double calculaGastoProducto(ElementosPelicula elementos); }
class ContableMiedo extends ContablecalculaGastoProducto(elementos){ return elementos.litrosSangre*getPrecioMercadoEuros();}
class ContableAmor extends ContablecalculaGastoProducto(elementos){ return elementos.kilosCebolla*getPrecioMercadoEuros();}
class peliculaDeAmor{main Camara camara = new Camara(4);integer Plano = 6;integer escena = 8;integer kilosCebolla= 4;String [] actores = [hulbrainer -> datosHulbrainer, kevincosnerjose ->datosKevincosnerjose, avaganer->datosAvaganer];......ElementosPelicula elementosUsados = new ElementosPeliculaAmor(camara,plano,escena,kilosCebolla)Double pagaDia = new ContableAmor().dameLaPagaStaff(elementosUsados);}extract method
Estas son una serie de consideraciones sobre el código de ejemplo de Extract method de la web de sourcemaking.com
que pasa de la forma que se puede ver en el archivo de moonEdit extract method archive
a ser el siguiente código
void printOwing(double previousAmount) {
Enumeration e = _orders.elements();
double outstanding = previousAmount * 1.2;
// print banner
System.out.println ("**************************");
System.out.println ("***** Customer Owes ******");
System.out.println ("**************************");
// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
//print details
System.out.println ("name:" + _name);
System.out.println ("amount" + outstanding);
}
que pasa de la forma que se puede ver en el archivo de moonEdit extract method archive
a ser el siguiente código
void printOwing(double previousAmount)
{
printBanner();
printDetails(calculateOutstanding(previusAmount*1.2));
}
void printBanner()
{
System.out.println ("**************************");
System.out.println ("***** Customer Owes ******");
System.out.println ("**************************");
}
void printDetails(Double outstandingArg)
{
System.out.println ("name:" + _name);
System.out.println ("amount" + outstandingArg);
}
Double calculateOutstanding(Double previousValue)
{
Double result = previousValue;
Enumeration e = _orders.elements();
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding result += each.getAmount();
}
return result;
}
lunes, 1 de agosto de 2011
Reflexiones aplicación refactoring
A partir del pseudo código de ejemplo de Form Template Method, de la web sourcemaking.com/refactoring se me planteó la duda sobre como hacer que este código funcione, y esto es lo que sale, con ejemplos de uso de :
para ver paso a paso como lo he hecho puedes descargar este archivo de MoonEdit form template method.me
pseudo código Original
en el que expone el problema para usar Form Template Method.
utilizando las refactorizaciones:
llego al siguiente código (tambien añadida la especificacion de que base requiera un importante cálculo para su obtención)
bad Smell, cosas que me huelen mal del código y que aún no tengo claro el refactoring:
para ver paso a paso como lo he hecho puedes descargar este archivo de MoonEdit form template method.me
pseudo código Original
en el que expone el problema para usar Form Template Method.
class Site
class Residential extends Site
public Double getBillableAmount()
{
return double base=_units*_rate;
double tax=base * Site.TAX_RATE;
return base+tax;
}
class Lifeline extends Site
public Double getBillableAmount()
{
double base=_units*_rate * 0,5;
double tax=base * Site.TAX_RATE*0,2;
return base+tax;
}
Proponiendo en su portal esta solución:
class Site
function Double getBillableAmount()
{
return getBaseAmount() + getTaxAmount();
}
funtion Double abstract getBaseAmount();
funcion Double abstract getTaxAmount();
class Residential extends Site
function Double getBaseAmount()
{
Double base= _units*_rate;
return base;
}
funtion Double getTaxAmount()
double tax=base * Site.TAX_RATE;
return tax;
}
class Lifeline extends Site
function Double getBaseAmount()
{
Double base= _units*_rate*0,5;
return base;
}
funtion Double getTaxAmount()
double tax=base * Site.TAX_RATE*0,2;
return tax;
}
utilizando las refactorizaciones:
- replace temp with query
- pull up method
- form template method
- pull up field
- self encapsulate field
- lazy initialization
llego al siguiente código (tambien añadida la especificacion de que base requiera un importante cálculo para su obtención)
// Refactoring about Form template method code in sourcemaking.com
class Site
{
Double base;
public Site()
{
setBase(undefined);
}
private Double getBase()
{
return this.base();
}
private setBase (Double base)
{
this.base = getBaseAmount();
}
public Double getBillableAmount()
{
return getBaseAmount()+ getTaxAmount();
}
private Abstract getBaseAmount();
private Abstract getTaxAmount();
}
class Residential extends Site
{
private Double getBaseAmount()
{
Double result = espensive calculus;
setBase(result);
return result;
}
private Double getTaxAmount()
{
if (!defined(getBase()) getBaseAmount();
return getBase() * Site.TAX_RATE;
}
}
class Lifeline extends Site
{
private Double getBaseAmount()
{
Double result = espensive diferent calculus;
setBase(result);
return result;
}
private Double getTaxAmount()
{
if (!defined(getBase()) getBaseAmount();
return getBase() * Site.TAX_RATE*0,2;
}
}
//SMELL : similar code in two subclases
//replace temp with query<- composing methods
//pull up method <- Dealing with Generalizaton
//form template method <- Dealing with Generalization
//pull up field <- Dealing with generalization
//self Encapsulate Fiel <- Organizing data
//lazy initialization
bad Smell, cosas que me huelen mal del código y que aún no tengo claro el refactoring:
- la linea if(!defined(getBase())
- ¿a que igualo this.base en la inicialización? a undefined, a null, a 0, a DOUBLE_NULL_VALUE
Suscribirse a:
Entradas (Atom)