Overview

VS Factory Patterns

Example

diagram

Factory Object Set-up and Delegation

public class UIToolKit {
    WidgetFactory wfactory;

    public UIToolKit (WidgetFactory wf) {
        this.wfactory = wf;
    }

    public void PopUpPrinterDialog() {
        DialogWindow d= wfactory.createDialogWindow("Printer Setup");
        d.add ( wfactory.createButton(OK_Button) );
        d.add ( wfactory.createButton(Cancel_Button) ); 

        d.showWindow();
    }
}
public class DriverForWinXP {
    // setup a specific widget factory
    WidgetFactory wf = new WinXPWidgetFactory();

    // start a client program
    UIToolKit ui = new UIToolKiet(wf);

    // rest of code
}

Class Diagram for GUIFactory

diagram

Class Diagram for Abstract Factory Pattern

diagram

Participants

Other Example

Making Factories for Ingredients (Abstract Factory)

public interface PizzaIngredientFactory {
    public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
    public Veggies[] createVeggies();
    public Pepperoni createPepperoni();
    public Clams createClam(); 
}

Concrete PizzaIngredientFactory (Factory Object)

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    public Dough createDough() {
        return new ThinCrustDough();
    }

    public Sauce createSauce() {
        return new MarinaraSauce();
    }

    public Cheese createCheese() {
        return new ReggianoCheese();
    }

    public Veggies[] createVeggies() {
        Veggies veggies[] = {new Garlic(), new Onion(), new Mushroom(), 
        new RedPepper() };
        return veggies;
    }

    public Pepperoni createPepperoni() {
        return new SlicedPepperoni();
    }

    public Clams createClam() {
        return new FreshClams();
    }
}

Pizza product class

public abstract class Pizza {
    String name;
    Dough dough;
    Sauce sauce;
    Veggies veggies[];
    Cheese cheese;

    abstract public void prepare();

    public void bake() {
        System.out.println("Bake for 25 minutes at 350");
    }

    public void cut() {
        System.out.println("Cutting the pizza into diagonal slices");
    }
    
    public void box() {
        System.out.println("Place pizza in official PizzaStore box");
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public String toString() {
        return this.getName();
    }
}
public class NYPizzaStore extends PizzaStore {
    protected Pizza createPizza(String item) {
        Pizza pizza = null;
        PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();

        if (item.equals("cheese")) {
            pizza = new CheesePizza(ingredientFactory);
            pizza.setName("New York Style Cheese Pizza");
        } else if (item.equals("veggie")) {
            pizza = new VeggiePizza(ingredientFactory);
            pizza.setName("New York Style Veggie Pizza");
        } else if (item.equals("clam")) {
            pizza = new ClamPizza(ingredientFactory);
            pizza.setName("New York Style Clam Pizza");
        } else if (item.equals("pepperoni")) {
            pizza = new PepperoniPizza(ingredientFactory);
            pizza.setName("New York Style Pepperoni Pizza");
        }

        return pizza;
    }
}
public class CheesePizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;

    public CheesePizza(PizzaIngredientFactory ingredientFactory) {
        this.ingredientFactory = ingredientFactory;
    }

    void prepare() {
        System.out.println("Preparing " + name);
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
}

What has changed?

  1. Instantiating PizzaStore.
    PizzaStore nyPizzaStore = new NYPizzaStore();
    
  2. Order.
    nyPizzaStore.orderPizza(“cheese”);
    
  3. orderPizza() calls createPizza().
    Pizza pizza = createPizza(“cheese”);
    
  4. BEGIN of Changed Flow for Ingredient Factory.
  5. createPizza() now needs ingredientFactory.
    Pizza pizza = new CheesePizza(nyIngredientFactory);
    
  6. prepare() creates ingredients using ingredient factory.
    void prepare(){
    dough = ingredientFactory.createDough();
    sauce = ingredientFactory.createSauce();
    cheese = ingredientFactory.createCheese();
    }
    
  7. END of Changed Flow for Ingredient Factory.
  8. Now it is ready. orderPizza() calls bake(), cut(), box().

When to Use Abstract Factory Pattern?

Abstract Factory Pattern

diagram
Supporting new kinds of products is difficult (not impossible, but costly)
diagram
Supporting additional factory object is easy

Summary