Factory Pattern from Head First Design Patterns


In this post, we will learn Factory Pattern implementation with examples from Head First Design Patterns Book.
Table of contents
  1. Overview
  2. Class Diagram
  3. Implementation with example
  4. Conclusion (Source code on Github Repository)
  5. References

1. Overview

Factory Method Pattern defined
The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide 
which class to instantiate. Factory Method lets a class defer instantiation of subclasses.
When to use the Factory Pattern,
Use the Factory Method pattern when
  • a class can't anticipate the class of objects it must create
  • a class wants its subclasses to specify the objects it creates
  • classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate
Depend upon abstraction, don't depend upon concrete classes.
This principle is applied to factory pattern implementation with examples.

2. Class Diagram

The above class diagram is a generic class diagram, we use this generic class diagram to implement Pizza Store example.

3. Implementation with Example


In this example, I have used Pizza Store Application from Head First Design Pattern Book.
Let's draw a class diagram for Pizza Store Application example.
Let's write source code for Pizza Store application using the Factory pattern.
Step 1: Create an abstract Pizza class, which abstract pizza related data.
package headfirst.factory.pizzas;

import java.util.ArrayList;
abstract public class Pizza {
 String name;
 String dough;
 String sauce;
 ArrayList toppings = new ArrayList();

 public String getName() {
  return name;
 }

 public void prepare() {
  System.out.println("Preparing " + name);
 }

 public void bake() {
  System.out.println("Baking " + name);
 }

 public void cut() {
  System.out.println("Cutting " + name);
 }

 public void box() {
  System.out.println("Boxing " + name);
 }

 public String toString() {
  // code to display pizza name and ingredients
  StringBuffer display = new StringBuffer();
  display.append("---- " + name + " ----\n");
  display.append(dough + "\n");
  display.append(sauce + "\n");
  for (int i = 0; i < toppings.size(); i++) {
   display.append((String )toppings.get(i) + "\n");
  }
  return display.toString();
 }
}
Step 2 : Create Concrete Pizza class - CheesePizzaClamPizza,VeggiePizza and PepperoniPizza java classes.
public class CheesePizza extends Pizza {
 public CheesePizza() {
  name = "Cheese Pizza";
  dough = "Regular Crust";
  sauce = "Marinara Pizza Sauce";
  toppings.add("Fresh Mozzarella");
  toppings.add("Parmesan");
 }
}
public class ClamPizza extends Pizza {
 public ClamPizza() {
  name = "Clam Pizza";
  dough = "Thin crust";
  sauce = "White garlic sauce";
  toppings.add("Clams");
  toppings.add("Grated parmesan cheese");
 }
}
public class VeggiePizza extends Pizza {
 public VeggiePizza() {
  name = "Veggie Pizza";
  dough = "Crust";
  sauce = "Marinara sauce";
  toppings.add("Shredded mozzarella");
  toppings.add("Grated parmesan");
  toppings.add("Diced onion");
  toppings.add("Sliced mushrooms");
  toppings.add("Sliced red pepper");
  toppings.add("Sliced black olives");
 }
}
public class PepperoniPizza extends Pizza {
 public PepperoniPizza() {
  name = "Pepperoni Pizza";
  dough = "Crust";
  sauce = "Marinara sauce";
  toppings.add("Sliced Pepperoni");
  toppings.add("Sliced Onion");
  toppings.add("Grated parmesan cheese");
 }
}
Step 3: Create a Factory Pattern class - SimplePizzaFactory java class.
public class SimplePizzaFactory {

 public Pizza createPizza(String type) {
  Pizza pizza = null;

  if (type.equals("cheese")) {
   pizza = new CheesePizza();
  } else if (type.equals("pepperoni")) {
   pizza = new PepperoniPizza();
  } else if (type.equals("clam")) {
   pizza = new ClamPizza();
  } else if (type.equals("veggie")) {
   pizza = new VeggiePizza();
  }
  return pizza;
 }
}
Step 4: Let's test the Factory Pattern - PizzaTestDrive java class.
public class PizzaTestDrive {
 
 public static void main(String[] args) {
  SimplePizzaFactory factory = new SimplePizzaFactory();
  PizzaStore store = new PizzaStore(factory);

  Pizza pizza = store.orderPizza("cheese");
  System.out.println("We ordered a " + pizza.getName() + "\n");
 
  pizza = store.orderPizza("veggie");
  System.out.println("We ordered a " + pizza.getName() + "\n");
 }
}
Output :
Preparing Cheese Pizza
Baking Cheese Pizza
Cutting Cheese Pizza
Boxing Cheese Pizza
We ordered a Cheese Pizza

Preparing Veggie Pizza
Baking Veggie Pizza
Cutting Veggie Pizza
Boxing Veggie Pizza
We ordered a Veggie Pizza

4. Conclusion

In this post, we have learned the Factory Pattern from Head First Design Patterns book. There is a separate post for Factory Pattern in detail with examples, advantages, real-world examples.
All the source code for this post available on Github Repo. This is an eclipse project so you can import into your workspace and play with it.

5. Reference

Comments