More design patterns

Last week I had a post where I briefly described the history and basis for design patterns and then went on to look at Singletons and Factories. Today lets consider the last two of the Creational patterns, the builder and the prototype.

The prototype pattern is similar to the factory pattern but differs in that it does not create an entire new object from scratch. The prototype is sometimes referred to as a clone and contains all of the state information from the original object at the time of cloning. The prototype is like making a photocopy of the original and then modifying the photocopy. In Java a prototype is usually an Interface that would be implemented as a  concrete-prototype. The following is a Java example of a prototype extracted from Wikipedia.

/**
 * Prototype class
 */
interface Prototype {
    void setX(int x);
    void printX();
    int getX();
}

/**
 * Implementation of prototype class
 */
class PrototypeImpl implements Prototype, Cloneable {
    private int x;

    public PrototypeImpl(int x) {
        setX(x);
    }

    public void setX(int x) {
        this.x = x;
    }

    public void printX() {
        System.out.println("Value: " + getX());
    }

    public int getX() {
        return x;
    }

    public PrototypeImpl clone() throws CloneNotSupportedException {
        return (PrototypeImpl) super.clone();
    }
}

/**
 * Client code
 */
public class PrototypeTest {
    public static void main(String args[]) 
                            throws CloneNotSupportedException {
        PrototypeImpl prototype = new PrototypeImpl(1000);

        for (int y = 1; y < 10; y++) {
            // Create a defensive copy of the object to 
            // allow safe mutation
            Prototype tempotype = prototype.clone();

            // Derive a new value from the prototype's "x" value
            tempotype.setX(tempotype.getX() * y);
            tempotype.printX();
        }
    }
}

/*
 **Code output**

Value: 1000
Value: 2000
Value: 3000
Value: 4000
Value: 5000
Value: 6000
Value: 7000
Value: 8000
Value: 9000
*/

The second pattern that we want to look at today is the Builder. Builders and Factories seem very similar at a first glace but the builder is the more complex of the two. With a factory some internal logic determines what type of object you need and returns it right away. With a builder the returned object can be a composite object made up of a number of other objects. The example from Wikipedia for a builder is as follows:

 /** "Product" */
 class Pizza {
    private String dough = "";
    private String sauce = "";
    private String topping = ""; 

    public void setDough(String dough){ 
        this.dough = dough; 
    }
    public void setSauce(String sauce){ 
        this.sauce = sauce; 
    }
    public void setTopping(String topping){ 
        this.topping = topping;
    }
 }

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

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

    public abstract void buildDough();
    public abstract void buildSauce();
    public abstract void buildTopping();
 }

 /** "ConcreteBuilder" */
 class VeggiePizzaBuilder extends PizzaBuilder {
    public void buildDough(){ 
        pizza.setDough("cross"); 
    }
    public void buildSauce(){ 
        pizza.setSauce("mild"); 
    }
    public void buildTopping(){ 
        pizza.setTopping("ham+pineapple");
    }
 }

 /** "ConcreteBuilder" */
 class SpicyPizzaBuilder extends PizzaBuilder {
    public void buildDough(){ 
        pizza.setDough("pan baked"); 
    }
    public void buildSauce(){ 
        pizza.setSauce("hot"); 
    }
    public void buildTopping(){ 
        pizza.setTopping("pepperoni+salami");
    }
 }

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

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

    public void constructPizza() {
       pizzaBuilder.createNewPizzaProduct();
       pizzaBuilder.buildDough();
       pizzaBuilder.buildSauce();
       pizzaBuilder.buildTopping();
    }
 }

 /** A customer ordering a pizza. */
 class BuilderExample {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        PizzaBuilder veggiePizzaBuilder = new VeggiePizzaBuilder();
        PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();

        waiter.setPizzaBuilder( hawaiianPizzaBuilder );
        waiter.constructPizza();

        Pizza pizza = waiter.getPizza();

        waiter.setPizzaBuilder( spicyPizzaBuilder );
        waiter.constructPizza();

        Pizza anotherPizza = waiter.getPizza();
    }
 }

I’m kinda partial to the pizza builder example, I think it really drives the point home [grin]. In the next installment of design patterns, we’ll start to look at the Structural Objects.

This entry was posted in General and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *