Factory Pattern: Kenneth M. Anderson University of Colorado, Boulder CSCI 4448/6448 - Lecture 21 - 11/06/2007
Factory Pattern: Kenneth M. Anderson University of Colorado, Boulder CSCI 4448/6448 - Lecture 21 - 11/06/2007
Lecture Goals
Cover Material from Chapters 4 of the Design Patterns Textbook Factory Pattern Abstract Factory Pattern
Obvious Problems: needs to be recompiled each time a dep. changes add new classes, change this code remove existing classes, change this code This means that this code violates the open-closed principle and the encapsulate what varies design principle
3
PizzaStore Example
We have a pizza store program that wants to separate the process of creating a pizza with the process of preparing/ordering a pizza Initial Code: mixed the two processes
1 public class PizzaStore { 2 Pizza orderPizza(String type) { 3 4 Pizza pizza; 5 6 if (type.equals("cheese")) { 7 pizza = new CheesePizza(); 8 } else if (type.equals("greek")) { 9 pizza = new GreekPizza(); 10 } else if (type.equals("pepperoni")) { 11 pizza = new PepperoniPizza(); 12 } 13 14 pizza.prepare(); 15 pizza.bake(); 16 pizza.cut(); 17 pizza.box(); 18 19 return pizza; 20 } 21 22 Note: excellent example of coding to an interface 23 } 24
Creation
Creation code has all the same problems as the code on the previous slide
Preparation
1 public class SimplePizzaFactory { 2 3 public Pizza createPizza(String type) { 4 if (type.equals("cheese")) { 5 return new CheesePizza(); 6 } else if (type.equals("greek")) { 7 return new GreekPizza(); 8 } else if (type.equals("pepperoni")) { 9 return new PepperoniPizza(); 10 } 11 } 12 13 } 14
factory
Factory Products
Pizza prepare() bake() cut() box()
CheesePizza
VeggiePizza
PepperoniPizza
While this is nice, its not as exible as it can be: to increase exibility we need to look at two design patterns: Factory Method and Abstract Factory
6
Factory Method
To demonstrate the factory method pattern, the pizza store example evolves to include the notion of different franchises that exist in different parts of the country (California, New York, Chicago) Each franchise will need its own factory to create pizzas that match the proclivities of the locals However, we want to retain the preparation process that has made PizzaStore such a great success The Factory Method Design Pattern allows you to do this by placing abstract, code to an interface code in a superclass placing object creation code in a subclass PizzaStore becomes an abstract class with an abstract createPizza() method We then create subclasses that override createPizza() for each region
Factory Method
This class is a (very simple) OO framework. The framework provides one service prepare pizza. The framework invokes the createPizza() factory method to create a pizza that it can prepare using a welldened, consistent process. A client of the framework will subclass this class and provide an implementation of the createPizza() method. Any dependencies on concrete product classes are encapsulated in the subclass.
8
Nice and Simple. If you want a NY-Style Pizza, you create an instance of this class and call orderPizza() passing in the type. The subclass makes sure that the pizza is created using the correct style. If you need a different style, create a new subclass.
9
ConcreteProduct
Factory Method leads to the creation of parallel class hierarchies; ConcreteCreators produce instances of ConcreteProducts that are operated on by Creators via the Product interface
10
11
12
Demonstration
Lets look at some code The FactoryMethod directory of this lectures src.zip le contains an implementation of the pizza store using the factory method design pattern It even includes a le called DependentPizzaStore.java that shows how the code would be implemented without using this pattern DependentPizzaStore is dependent on 8 different concrete classes and 1 abstract interface (Pizza) PizzaStore is dependent on just the Pizza abstract interface (nice!) Each of its subclasses is only dependent on 4 concrete classes furthermore, they shield the superclass from these dependencies
13
Moving On
The factory method approach to the pizza store is a big success allowing our company to create multiple franchises across the country quickly and easily But, bad news, we have learned that some of the franchises while following our procedures (the abstract code in PizzaStore forces them to) are skimping on ingredients in order to lower costs and increase margins Our companys success has always been dependent on the use of fresh, quality ingredients so Something Must Be Done!
14
15
Note the introduction of more abstract classes: Dough, Sauce, Cheese, etc.
16
This factory ensures that quality ingredients are used during the pizza creation process while also taking into account the tastes of people who live in Chicago But how (or where) is this factory used?
17
First, alter the Pizza abstract base class to make the prepare method abstract
18
Then, update Pizza subclasses to make use of the factory! Note: we no longer need subclasses like NYCheesePizza and ChicagoCheesePizza because the ingredient factory now handles regional differences
19
We need to update our PizzaStore subclasses to create the appropriate ingredient factory and pass it to each Pizza subclass in the createPizza factory method.
20
21
Demonstration
Examine and execute the code located in the Abstract Factory directory of the src.zip le associated with this lecture
22
factory
Client
AbstractProductA Interface
AbstractProductB Interface
ProductA1
ProductA2
ProductB1
ProductB2
23
Wrapping Up
All factories encapsulate object creation Simple Factory is not a bona de design pattern but it is simple to understand and implement Factory Method relies on inheritance: object creation occurs in subclasses Abstract Factory relies on composition: object creation occurs in concrete factories Both can be used to shield your applications from concrete classes And both can aide you in applying the dependency inversion principle in your designs
24
Coming Up Next
Lecture 22: Singleton and Command Patterns Read Chapters 5 and 6 of the Design Patterns Textbook Lecture 23: Adapters and Template Methods Read Chapters 7 and 8 of the Design Patterns Textbook
25