El patrón de decorador se utiliza para agregar capacidades a los objetos dinámicamente (es decir, en tiempo de ejecución). Normalmente, el objeto tendrá sus capacidades corregidas cuando escriba la clase. Pero un punto importante es que la funcionalidad del objeto se extiende de forma transparente para el cliente del objeto porque implementa la misma interfaz que el objeto original que delega la responsabilidad del objeto decorado.
El patrón de decorador funciona en escenarios donde hay muchas funciones opcionales que un objeto puede tener. Sin el patrón de decorador, deberá crear una clase diferente para cada configuración de opción de objeto. Un ejemplo que es bastante útil proviene del Head First Design Patterns libro de O'Reilly. Utiliza un ejemplo de cafetería que suena como StarBucks.
Así que tiene el café básico con un método como el costo.
public double cost(){
return 3.45;
}
A continuación, el cliente puede agregar la crema que cuesta 0,35 por lo que ahora crea una clase CoffeeCream con el método de costo:
public double cost(){
return 3.80;
}
A continuación, el cliente lo desea, puede Mocha, que cuesta 0,5, y es posible que quieran Mocha con crema o moca sin crema. Entonces creas las clases CoffeeMochaCream y CoffeeMocha. Entonces un cliente quiere crema doble para que crees una clase de CoffeeCreamCream ... etc. Lo que terminas con explosión de clase. Disculpe el pobre ejemplo utilizado. Es un poco tarde y sé que es trivial pero expresa el punto.
su lugar se puede crear una clase abstracta de artículos con un método de costo abstracta:
public abstract class Item{
public abstract double cost();
}
Además, puede crear una clase de café de hormigón que se extiende artículo:
public class Coffee extends Item{
public double cost(){
return 3.45;
}
}
A continuación, se crea un CoffeeDecorator que extiende la misma interfaz y contiene un artículo.
public abstract class CoffeeDecorator extends Item{
private Item item;
...
}
continuación, puede crear decoradores concretas para cada opción:
public class Mocha extends CoffeeDecorator{
public double cost(){
return item.cost() + 0.5;
}
}
Note como el decorador no le importa qué tipo de objeto se está terminando con tal de que se trata de un artículo? Utiliza el costo() del objeto del artículo y simplemente agrega su propio costo.
public class Cream extends CoffeeDecorator{
public double cost(){
return item.cost() + 0.35;
}
}
Ahora bien, es posible que un gran número de configuraciones con estas pocas clases: por ejemplo,
Item drink = new Cream(new Mocha(new Coffee))); //Mocha with cream
o
Item drink = new Cream(new Mocha(new Cream(new Coffee))));//Mocha with double cream
Y así sucesivamente.
Aha, supongo que usted es un lector de Head First Design Patterns? – dhiller
Encontré esta respuesta más fácil de comprender que el artículo de Wikipedia. –
@dhiller Yep. Design Patterns fue el primero que probé y comencé a recomendarlos a todos mis alumnos. –