Professional Documents
Culture Documents
Factory Design Patterns: CECS277 Fall 2017 Mimi Opkins
Factory Design Patterns: CECS277 Fall 2017 Mimi Opkins
CECS277
Fall 2017
Mimi Opkins
Factory Pattern
• Different Flavors
– Simple Factory
– Factory Method
– Abstract Factory
01/12/2022 2
What Pattern should we consider?
• We need to manage a shared network printer.
01/12/2022 4
PizzaStore in Objectville
• During the ordering of a Pizza, we need to perform certain actions
on it:
– Prepare
– Bake
– Cut
– Box
return pizza;
}
if (type.equals("cheese")) {
pizza = new CheesePizza();
Code that varies
} else if (type.equals("pepperoni")) {
pizza = new PepperoniPizza();
pizza.prepare();
pizza.bake(); Code that stays
pizza.cut(); the same
pizza.box();
return pizza;
}
01/12/2022 7
PizzaStore in Objectville (cont)
01/12/2022 8
Solution?
Move the creation of Pizzas into a separate object!
public class SimplePizzaFactory {
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;
}
} 9
01/12/2022
SimplePizzaFactory
• Advantage: We have one place to go to add a new
pizza.
01/12/2022 10
Rework of PizzaStore
public class PizzaStore { Store is composed
SimplePizzaFactory factory; of a factory.
return pizza;
}
} 01/12/2022 11
Simple Factory Defined
• This is not an official pattern, but it is commonly
used.
• Not a bad place to start.
• When people think of “Factory”, they may actually be
thinking of this.
01/12/2022 12
Change Now Occurs…
• The PizzaStore is very popular and it needs to be
franchised.
– New York is interested
– Chicago is interested
– And perhaps one day Fairfax…
01/12/2022 13
Example
//Order pizza
nyStore.order(“Veggie”);
01/12/2022 14
More change happens…
01/12/2022 15
More change happens… (cont)
NYPizzaFactory nyFactory = new NYPizzaFactory();
NYPizzaStore nyStore = new NYPizzaStore(nyFactory);
//Order pizza
nyStore.order(“Veggie”);
myStore.ScheduleDelivery();
01/12/2022 17
A Framework for Pizza Store
public abstract class PizzaStore {
pizza.prepare();
. . .
return pizza;
}
}
NOTE: We are using inheritance here to create the pizzas, not composition.
Also, the constructor for PizzaStore has been removed.
01/12/2022 18
NYPizzaStore
public class NYPizzaStore extends PizzaStore {
void ScheduleDelivery();
}
The subclass is defining how the pizza is created….and it is also providing
unique functionality that is applicable to New York.
01/12/2022 19
Factory Method
public abstract class PizzaStore {
pizza.prepare();
. . .
return pizza;
}
}
Factory Method simply sets up an interface for creating a Product (in this
case, a type of Pizza). Subclasses decide which specific Product to
create.
01/12/2022 20
Test Drive
2) nyStore.orderPizza("cheese");
01/12/2022 21
Factory Method Defined
GoF Intent: “Defines an interface for creating an object, but
lets subclasses decide which class to instantiate. Factory
Method lets a class defer instantiation to subclasses.”
01/12/2022 22
Definitions
• Product - abstraction of the object that we need to create (Pizza)
01/12/2022 23
IMPORTANT
01/12/2022 24
Lab
public abstract class PizzaStore {
01/12/2022 25
Parameterized Factory Method
• Another example is actually a Parameterized Factory
Method since it can make more than one object
(based on some input parameter).
01/12/2022 26
Simple Factory Method
public abstract class PizzaStore {
Pizza createPizza() {
return new NYStylePizza(); //just one product returned
}
}
01/12/2022 27
Simple Factory Method (with Default)
public abstract class PizzaStore {
01/12/2022 28
SimUDuck
public class MallardDuck extends Duck { MallardDuck is tied to
two specific
public MallardDuck() { implementations.
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
Developer would
have to know to do
this. The design
does not enforce it.
01/12/2022 29
Before
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
01/12/2022 30
After
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
Factory Methods
abstract FlyBehavior createFly();
abstract QuackBehavior createQuack();
public Duck() {
flyBehavior = createFly();
quackBehavior = createQuack();
}
}
01/12/2022 31
Now we create MallardDuck…
public class MallardDuck extends Duck {
Note that the
public MallardDuck() { constructor is empty.
}
FlyBehavior createFly() {
return FlyWithWings();
}
Developer is “forced” to
QuackBehavior createQuack() { specify implementations of
return Quack(); Fly and Quack.
}
01/12/2022 32
Alternative Design: Default Behavior
QuackBehavior createQuack() {
return DefaultQuack();
}
public Duck() {
flyBehavior = createFly();
quackBehavior = createQuack();
}
}
01/12/2022 33
Factory Method and Template
public abstract class CaffeineBeverage {
void addCondiments(Condiment c) {
//add condiment c
}
}
01/12/2022 34
Summary
• Pattern Name – Factory Method
• Problem – Do not want our framework to be tied to a
specific implementation of an object.
• Solution
– Let subclass decide which implementation to use (via
use of an abstract method)
– Tie the Creator with a specific Product Implementation
• Consequences
– Simple Factory Method
– Simple Factory Method with Default Behavior
– Parameterized Factory Method
– Factory and Template Together
01/12/2022 35
Changes..
• Objectville Pizza HQ gets complaints that the different
franchises are not using quality ingredients. They decide
that all Pizzas must be composed of the following
ingredients:
– Dough, Sauce, Cheese, Veggies, Pepperoni, and Clams.
• New York says those ingredients are fine, but they want to
use their own regional ingredients for all types of pizza, for
example
– Dough = Thin Crust Dough
– Sauce = Marinara
– Cheese = Reggiano
– Veggies = Garlic, Onion
01/12/2022 36
Pizza
public class Pizza {
Dough dough;
Sauce sauce;
Pizza becomes composed of
Veggies veggies[];
different ingredients.
Cheese cheese;
Pepperoni pepperoni;
Clams clam;
Question: How do we
get these ingredients
. . . associated with a
Pizza??
}
01/12/2022 37
One idea…Constructor w/many parameters
this.dough = d;
this.sauce = s; Makes sense…whenever
this.veggies = v; you create a pizza, you
this.cheese = c; must specify these
this.pepperoni = p; ingredients…
this.clam = c;
}
}
01/12/2022 38
Rework NYPizzaStore
public class NYPizzaStore extends PizzaStore {
if (item.equals("cheese")) {
return new NYStyleCheesePizza(new ThinCrustDough(),
new Marinara(), new Reggiano(), null, null );
} else if (item.equals("veggie")) {
return new NYStyleVeggiaPizza(new ThinCrustDough(),
new Marinara(), new Reggiano(), mew Garlic() , null)
}
}
This will cause a lot of maintenance headaches!!! Imagine what happens
when we create a new pizza!
We know that we have a certain set of ingredients that are used for New
York..yet we have to keep repeating that set with each constructor. Can we
define this unique set just once??
39
01/12/2022
PizzaIngredientFactory
Create an interface for creating the different ingredients of Pizza.
01/12/2022 40
NYPizzaIngredientFactory
01/12/2022 41
CheesePizza
public class CheesePizza extends Pizza { Instead of many
ingredient parameters,
PizzaIngredientFactory ingredientFactory; we just pass one.
void prepare() {
dough = ingredientFactory.createDough();
Creation
sauce = ingredientFactory.createSauce();
delegated
cheese = ingredientFactory.createCheese();
}
}
if (item.equals("cheese")) {
pizza = new CheesePizza(ingredientFactory);
} else if (item.equals("veggie")) {
pizza = new VeggiePizza(ingredientFactory);
} else if (item.equals("clam")) {
pizza = new ClamPizza(ingredientFactory);
} else if (item.equals("pepperoni")) {
pizza = new PepperoniPizza(ingredientFactory);
}
return pizza;
01/12/2022 43
Abstract Factory Defined
01/12/2022 44
Factory Method vs. Abstract Factory
• Factory Method
– Uses inheritance to create a Concrete Product
– Sub classes decide which Concrete Product to use
• Abstract Factory
– Uses composition to create objects
– The objects created were a part of a family of objects.
For example, NY region had a specific set of ingredients.
– An abstract factory actually contains one or more
Factory Methods!
01/12/2022 45
Database Example
• Imagine you wanted to created a database manager object as an
enterprise component. This object must not be tied to a specific
database implementation.
• Oracle, SQL Server, Informix, etc will have their own version of
these Sub Products.
01/12/2022 46
DatabaseFactory
public abstract class DatabaseFactory
{
public abstract IDbCommand CreateCommand();
public abstract IDbCommand CreateCommand(string cmdText);
public abstract IDbCommand CreateCommand(string cmdText, IDbConnection cn);
public abstract IDbConnection CreateConnection();
public abstract IDbConnection CreateConnection(string cnString);
public abstract IDbDataAdapter CreateDataAdapter();
public abstract IDbDataAdapter CreateDataAdapter(IDbCommand selectCmd);
public abstract IDataReader CreateDataReader(IDbCommand dbCmd);
}
Each database implementation (Oracle, SQL Server, etc) will need to create
their own version of this DatabaseFactory.
01/12/2022 47
Abstract Factory and Singleton
• If you have many different Abstract Factories, you
probably just need one instance of each abstract
factory.
01/12/2022 48
A more interesting case…
What if NY Pizza Store wanted the flexibility to change their
ingredients all the time??
01/12/2022 49
What will happen??
• Class Explosion!
01/12/2022 50
Solution: Abstract Factory and Prototype
PizzaIngredientFactory ingredientFactory =
new NYPizzaIngredientFactory
(new ThinCrustDough(), new MarinaraSauce(),
new Provolone() );
01/12/2022 51
Solution: Abstract Factory and Prototype
01/12/2022 53
Summary
• Pattern Name – Abstract Factory
• Problem – Need to way to create a family of products
• Solution
– Create an interface for creating products
• Consequences
– Objects are created using interface
– Composition is used to create objects
– Abstract Factory and Singleton
– Abstract Factory and Prototype
01/12/2022 54
Credits
Jonathan Simon
jonathan_simon@yahoo.com