La necesidad de investigar sobre este patrón se presentó cuando necesitas agregar funcionalidades adicionales u otras características a la clase sin complicar el código o la lógica en sí, la mejor manera de explicarlo es con código:
PE: (Por ejemplo)
public String getDescripcion() {
return descripcion;
public abstract double precio();
// Ahora la clase que representa una Bebida en concreto
public class Batida extends Bebida {
public Batida() {
descripcion = "Batida";
}
public double precio() {
return 45;
}
}
// Antes de crear los complementos de las Bebidas debemos
// crear la clase que DECORA a los objetos Bebida con los
// complementos que luego seran agregados
public abstract class DecoradorComplementos extends Bebida {
public abstract String getDescripcion();
}
// Como ya tenemos la clase que DECORA a los objetos procedemos
// a crear los complementos
public class Leche extends DecoradorComplementos {
Bebida bebida; // Se necesita una instancia de la clase bebida para decorar
public String getDescripcion() {
// Aqui le sumamos a la descripcion de la bebida la descripcion del complemento
return bebida.getDescripcion() + ", Leche";
}
public double precio() {
// Aqui le sumamos el precio del complemento al precio de la bebida
return 10 + bebida.precio();
}
}
// Finalmente la implementacion (Uso) de estas clases seria
public class Cafeteria {
public static void main(String[] args) {
Bebida cafeMocachino = new Mocachino();
Bebida batidaEspecial = new Batida();
// Despachemos el Cafe Mocachino sin complemento
System.out.println(cafeMocachino.getDescripcion() + " quot; + cafeMocachino.precio());
// Ahora la batida con un complemento
// Le pasamos la instancia de la bebida al complemento
batidaEspecial = new Leche(batidaEspecial);
System.out.println(batidaEspecial.getDescripcion() + " quot; + batidaEspecial.precio());
}
}
PE: (Por ejemplo)
Imaginen una cafetería que posee varias bebidas, por cada bebida hay un precio específico y el cliente puede agregar complementos a la bebida que no son exclusivos de la misma y que por consiguiente agregan un monto adicional al precio final y una nueva descripción a la Bebida en cuestión, como:
"Mocachino, Canela, Suspiro, Fresas" por decir algo
Partiendo de esto tenemos:
Bebidas:
- Batida
- Expreso
- Descafeinado
- Mocachino
- Jugo Natural
Complementos:
- Cada servicio ser servido con: Leche de Soja, Soja, Crema, Frutas y mas...
"Mocachino, Canela, Suspiro, Fresas" por decir algo
Partiendo de esto tenemos:
Bebidas:
- Batida
- Expreso
- Descafeinado
- Mocachino
- Jugo Natural
Complementos:
- Cada servicio ser servido con: Leche de Soja, Soja, Crema, Frutas y mas...
Veamos el código en Java:
// Clase Abstracta (no se puede instanciar) que define la estructura
// base de la Bebida
public abstract class Bebida {
String descripcion = "Bebida sin definir";
// Clase Abstracta (no se puede instanciar) que define la estructura
// base de la Bebida
public abstract class Bebida {
String descripcion = "Bebida sin definir";
public String getDescripcion() {
return descripcion;
}
public abstract double precio();
}
// Ahora la clase que representa una Bebida en concreto
public class Batida extends Bebida {
public Batida() {
descripcion = "Batida";
}
public double precio() {
return 45;
}
}
// Veamos otra Bebida
public class Mocachino extends Bebida {
public Mocachino() {
descripcion = "Mocachino";
}
public class Mocachino extends Bebida {
public Mocachino() {
descripcion = "Mocachino";
}
public double precio() {
return 35;
}
}
return 35;
}
}
// Antes de crear los complementos de las Bebidas debemos
// crear la clase que DECORA a los objetos Bebida con los
// complementos que luego seran agregados
public abstract class DecoradorComplementos extends Bebida {
public abstract String getDescripcion();
}
// Como ya tenemos la clase que DECORA a los objetos procedemos
// a crear los complementos
public class Leche extends DecoradorComplementos {
Bebida bebida; // Se necesita una instancia de la clase bebida para decorar
public Leche(Bebida bebida) {
this.bebida = bebida; // Aqui le pasamos la instancia a la variable interna
}
this.bebida = bebida; // Aqui le pasamos la instancia a la variable interna
}
public String getDescripcion() {
// Aqui le sumamos a la descripcion de la bebida la descripcion del complemento
return bebida.getDescripcion() + ", Leche";
}
public double precio() {
// Aqui le sumamos el precio del complemento al precio de la bebida
return 10 + bebida.precio();
}
}
// Finalmente la implementacion (Uso) de estas clases seria
public class Cafeteria {
public static void main(String[] args) {
Bebida cafeMocachino = new Mocachino();
Bebida batidaEspecial = new Batida();
// Despachemos el Cafe Mocachino sin complemento
System.out.println(cafeMocachino.getDescripcion() + " quot; + cafeMocachino.precio());
// Ahora la batida con un complemento
// Le pasamos la instancia de la bebida al complemento
batidaEspecial = new Leche(batidaEspecial);
System.out.println(batidaEspecial.getDescripcion() + " quot; + batidaEspecial.precio());
}
}
// El resultado de esta ejecucion seria:
Mocachino $35
Batida, Leche $55
Mocachino $35
Batida, Leche $55
En lo adelante para Nuevas Bebidas y Complementos la implementacion mas sencilla y rapida debido a esta forma de distribuir las responsabilidades.
Hasta la próxima...
Comentarios