2 abr 2013

Solución 12 - Patrón de diseño Builder


El patrón de diseño Builder te permite encapsular la funcionalidad y propiedades comunes entre diferentes objetos en un proceso de creación común.  Con ello, se obtiene mantenibilidad de los objetos resultantes, creando los contratos de clase para que su uso sea lo más robusto posible.


Definición de wikipedia: Como Patrón de diseño, el patrón builder (Constructor) es usado para permitir la creación de una variedad de objetos complejos desde un objeto fuente (Producto), el objeto fuente se compone de una variedad de partes que contribuyen individualmente a la creación de cada objeto complejo a través de un conjunto de llamadas a interfaces comunes de la clase Abstract Builder.


El patrón Builder se compone de 4 clases:
Director : Encargado de realizar el proceso de creación del objeto paso a paso.
AbstractBuilder (Builder) :  Contrato donde se especifica qué pasos son los del proceso de creación. De forma generalizada.
ConcreteBuilder : Implementa los pasos de forma individual.
Product : Objeto final a elaborar.




Ejemplo:
El ejemplo es un Builder de pizzas. El añadir nuevas pizzas consistirá en crear un nueva Pizza (Product) y un nuevo PizzaBuilder (ConcreteBuilder). Esta nueva Pizza heredará la plantilla del proceso de creación común a todas las pizzas.


/** "Abstract Builder" */
abstract
class PizzaBuilder {
   
protected Pizza pizza;

   
public Pizza getPizza() { return pizza; }
   
public void crearNuevaPizza() { pizza = new Pizza(); }

   
public abstract void buildMasa();
   
public abstract void buildSalsa();
   
public abstract void buildRelleno();
}
La clase AbstractBuilder tiene el contrato que cumplirá al ConcreteBuilder.
/** "ConcreteBuilder" */
class HawaiPizzaBuilder extends PizzaBuilder {
   
public void buildMasa()   { pizza.setMasa("suave"); }
   
public void buildSalsa()   { pizza.setSalsa("dulce"); }
   
public void buildRelleno() { pizza.setRelleno("chorizo+alcachofas"); }
}
/** "ConcreteBuilder" */
class PicantePizzaBuilder extends PizzaBuilder {
   
public void buildMasa()   { pizza.setMasa("cocida"); }
   
public void buildSalsa()   { pizza.setSalsa("picante"); }
   
public void buildRelleno() { pizza.setRelleno("pimienta+salchichón"); }
}

/** "Director" */
class Cocina {
   
private PizzaBuilder pizzaBuilder;

   
public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
   
public Pizza getPizza() { return pizzaBuilder.getPizza(); }

   
public void construirPizza() {
      pizzaBuilder
.crearNuevaPizza();
      pizzaBuilder
.buildMasa();
      pizzaBuilder
.buildSalsa();
      pizzaBuilder
.buildRelleno();
   
}
}

El proceso de elaboración se puede ver en el AbstractBuilder y se define de manera individual en los ConcreteBuilder. El Director solo pone en marcha el proceso paso a paso.

/** Un cliente pidiendo una pizza. */
class BuilderExample {
   
public static void main(String[] args) {
       Cocina cocina
= new Cocina();
       PizzaBuilder hawai_pizzabuilder
= new HawaiPizzaBuilder();
       PizzaBuilder picante_pizzabuilder
= new PicantePizzaBuilder();

       cocina
.setPizzaBuilder( hawai_pizzabuilder );
       cocina
.construirPizza();

       Pizza pizza
= cocina.getPizza();
   
}
}


No hay comentarios: