Design patterns IV : Creational Patterns J.Serrat 102759 Software Design October 20, 2013 Index 1 Singleton 2 Factory method 3 Abstract factory 4 Prototype 5 Builder
Design patterns IV : Creational Patterns
J.Serrat
102759 Software Design
October 20, 2013
Index
1 Singleton
2 Factory method
3 Abstract factory
4 Prototype
5 Builder
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Overview
Behavioural patterns characterize the ways in which classes orobjects interact and distribute responsibility
Structural patterns deal with the composition of classes orobjects to form larger structures (composite, bridge) or torealize new functionality (adapter . . . )
Creational patterns concern the process of object creation
3 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
Head-first design patterns. E. Freeman et al. O’Reilly, 2004
4 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
Motivation
sometimes in a design there are classes for which at most anobject must be instantiated
this object is often used by other objects/classes throughoutall our design
think of a printer spooler, a calculation, a clock, a userinterface dialog, the company CEO, a device driver. . .
it would wrong to instantiate more than one such objects,according to the requirements
5 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
Can you do that with a global variable, like a static one in Java ?
public class HPDeskJet1050Driver extends PrinterDriver {
public HPDeskJet1050() { //... }
public void initPrinter() { //... }
public void stopPrinter() { //... }
public void print(File file) { //... }
}
static PrinterDriver printerDriver = new HPDeskJet1050Driver();
yes, but the object is created when application starts, notwhen it is needed: lazy vs eager initialization
applying Singleton pattern is explicitly declaring your intentionof uniqueness
all designers know the Singleton trick
it’s a very easy pattern to apply
6 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
Silly example from Head-first design patterns: a chocolate boiler.
7 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
public ChocolateBoiler() {
empty = true;
boiled = false;
}
public void fill(){
if (isEmpty()) {
// fill in the boiler
// with milk and chocolate
empty = false;
boiled = false;
}
}
public void drain() {
if (!isEmpty() && isBoiled()) {
// drain boiled milk
// and chocolate
empty = true;
}
}
public void boil() {
if (!isEmpty() && !isBoiled()) {
// bring contents to a boil
boiled = true;
}
}
public boolean isEmpty() {
return empty;
}
public boolean isBoiled() {
return boiled;
}
8 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
private static ChocolateBoiler uniqueInstance = null;
private ChocolateBoiler() {
empty = true;
boiled = false;
}
// lazy initialization
public static ChocolateBoiler getInstance() {
if (uniqueInstance == null) {
return new ChocolateBoiler();
} else {
return uniqueInstance;
}
}
// rest of ChocolateBoiler methods
9 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
Intent
Ensure a class only has one instance, and provide a global point ofaccess to it.
Structure
declare constructor private
public static method to return the unique instance
either initialize unique instance (eager) or defer it to first callto get instance (lazy)
10 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
11 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
12 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
13 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
14 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
15 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
16 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
public static ChocolateBoiler getInstance() {
public static ChocolateBoiler getInstance() {
if (uniqueInstance==null) {
if (uniqueInstance==null) {
uniqueInstance = new ChocolateBoiler();
uniqueInstance = new ChocolateBoiler();
return uniqueInstance;
return uniqueInstance;
null
null
null
<object1>
<object1>
<object2>
<object2>
17 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
private static ChocolateBoiler uniqueInstance = null;
private ChocolateBoiler() {
empty = true;
boiled = false;
}
// lazy initialization
public static synchronized ChocolateBoiler getInstance() {
if (uniqueInstance == null) {
return new ChocolateBoiler();
} else {
return uniqueInstance;
}
}
// rest of ChocolateBoiler methods
18 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
How to deal with threads ?
by adding the synchronized keyword no two threads mayenter getInstance at the same time but must wait their turn
however, this may cause overhead (100 times slower)
synchronization is only needed before settinguniqueInstance and not anymore
if performance is not an issue (or there are not multiplethreads), do nothing
if singleton object is not expensive (time, memory) to create,do eager initialization
if it is, double checked locking
19 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
private static ChocolateBoiler uniqueInstance
= new ChocolateBoiler();
private ChocolateBoiler() {
empty = true;
boiled = false;
}
// eager initialization
public static ChocolateBoiler getInstance() {
return uniqueInstance;
}
// rest of ChocolateBoiler methods
20 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singletonpublic class ChocolateBoiler {
private boolean empty;
private boolean boiled;
private static volatile ChocolateBoiler uniqueInstance = null;
// volatile ensures multiple threads handle the attribute
// correctly when it is being initialized to the instance
private ChocolateBoiler() {
empty = true; boiled = false;
}
// double checked locking
public static ChocolateBoiler getInstance() {
if (uniqueInstance == null) {
synchronized ( ChocolateBoiler.class ) {
// therefore, only synchronize the first time
if (uniqueInstance == null) { // check again
uniqueInstance = new ChocolateBoiler();
}
}
return uniqueInstance;
}
21 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
How to deal with inheritance ?
singleton as an abstract class complicates the implementation,better avoid it
in Java, another way to create objects is to override clone()
and implement interface Cloneable
making the class final prevents cloning. Since Singleton isinherited directly from Object, the clone() method remainsprotected so it cannot be used
22 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Singleton
How to deal with inheritance ?
just in case Singleton class could inherit from another classthat has overriden clone(),
class MySingleton implements Cloneable {
@Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
// could return the instance but it seems misleading
// for the client code to do so from a clone = ’give
// a copy’ method
}
//...
}
23 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
Motivating example: an old example of Composite
build a maze for a computer game, where the player has tofind the way out
maze is made of rooms, a room knows its neighbours: anotherroom, a wall, or a door to another room
you can enter a room, door (changes room if open) and evena wall (if given the power to do so, change room)
now we focus on the creation of a maze, not representation(Composite) or players (State)
24 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
room r2 room r1
theDoor
wall
25 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
26 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory methodclass Room implements MapSite {
ArrayList<MapSite> sides = new ArrayList<MapSite>();
public setSide(int direction, MapSite ms) {
int index;
switch (direction) {
case North: index = 0; break;
case East: index = 1; break;
case South: index = 2; break;
case West: index = 3; break;
default: assert false;
sides.toArray()[index] = ms;
}
public Room(MapSite up, MapSite right,
MapSite down, Mapsite left) {
setSide(North, up);
setSide(East, right);
setSide(South, down);
setSide(West, left);
}
}
27 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
class MazeGame {
public Maze CreateMaze() {
Maze aMaze = new Maze();
Door theDoor = new Door();
Room r1 = new Room(new Wall(), new Wall(), new Wall(),
theDoor);
Room r2 = new Room(new Wall(), theDoor, new Wall(),
new Wall());
theDoor.setRooms(r1, r2);
aMaze.addRoom(r1);
aMaze.addRoom(r2);
return aMaze;
}
//...
}
28 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
The problem with CreateMaze() is its inflexibility: ithard-codes the maze layout and component classes.
Changing the layout and/or component classes meanschanging this method, either by overriding it—reimplementing the whole thing— or by changing parts of it—error-prone and doesn’t promote reuse.
The Factory Method and later Abstract Factory will make iteasy to change the classes that define the components of amaze.
29 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
Want to reuse an existing maze layout for a new gamecontaining enchanted mazes
an enchanted maze has new kinds of components:
DoorNeedingSpell, a door that can be locked and openedsubsequently only with a spellEnchantedRoom, a room with magic keys or spells.
How to change CreateMaze easily so that it creates a mazewith the same layout but with these new classes of room anddoor?
Call, instead of constructors, factory methods which createthe right class of objects depending on the factory subclassthey belong to.
30 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
31 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
With factory method
abstract class MazeGame {
public Maze createMaze() {
Maze aMaze = new Maze();
Door theDoor = makeDoor();
Room r1 = makeRoom(makeWall(), makeWall(), makeWall(),
theDoor);
Room r2 = makeRoom(makeWall(), theDoor, makeWall(),
makeWall());
theDoor.setRooms(r1, r2);
aMaze.addRoom(r1); aMaze.addRoom(r2);
return aMaze;
}
public abstract Room makeRoom(MapSite up, MapSite right,
MapSite down, MapSite left);
public abstract Door makeDoor();
public abstract Wall makeWall();
} //...
MazeGame game = new EnchantedMazeGame(); // new NormalMazeGame();
Maze maze = game.createMaze();32 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
Original code
class MazeGame {
public Maze createMaze() {
Maze aMaze = new Maze();
Door theDoor = new Door();
Room r1 = new Room(new Wall(), new Wall(), new Wall(),
theDoor);
Room r2 = new Room(new Wall(), theDoor, new Wall(),
new Wall());
theDoor.setRooms(r1, r2);
aMaze.addRoom(r1);
aMaze.addRoom(r2);
return aMaze;
}
}
//...
MazeGame game = new MazeGame();
Maze maze = game.createMaze();
33 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
Intent
Define an interface for creating an object, but let subclasses decidewhich class to instantiate. Factory Method lets a class deferinstantiation to subclasses.
Applicability
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 helpersubclasses, and you want to localize the knowledge of whichhelper subclass is the delegate
34 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
Structure
35 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
Motivating example: continuing the maze creation problem,
NormalRoom, NormalDoor and EnchantedRoom,DoorNeedingSpell is not the only difference between mazesof NormalMazeGame and EnchantedMazeGame
now maybe even walls are different
for each type of maze there is a different family of mapsites
the maze of a game is made either of [exclusive or] normalsites or enchanted sites or . . . whatever sites
36 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
37 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
38 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
With Abstract factory
class MazeGame {
public Maze createMaze(MazeFactory factory) {
Maze aMaze = new Maze();
Door theDoor = factory.makeDoor();
Room r1 = factory.makeRoom(factory.makeWall(),
factory.makeWall(), factory.makeWall(), theDoor,);
Room r2 = factory.makeRoom(factory.makeWall(), theDoor,
factory.makeWall(), factory.makeWall());
theDoor.setRooms(r1, r2);
return aMaze;
}
} //...
MazeFactory factory = new EnchantedMazeFactory();
// MazeFactory factory = new NormalMazeFactory();
MazeGame game = new MazeGame();
Maze maze = game.createMaze(factory);
39 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Factory method
With Factory Method
abstract class MazeGame {
public Maze createMaze() {
Maze aMaze = new Maze();
Door theDoor = makeDoor();
Room r1 = makeRoom(makeWall(), makeWall(), makeWall(),
theDoor);
Room r2 = makeRoom(makeWall(), theDoor, makeWall(),
makeWall());
theDoor.setRooms(r1, r2);
aMaze.addRoom(r1); aMaze.addRoom(r2);
return aMaze;
}
public abstract Room makeRoom(MapSite up, MapSite right,
MapSite down, MapSite left);
public abstract Door makeDoor();
public abstract Wall makeWall();
} //...
MazeGame game = new EnchantedMazeGame(); // new NormalMazeGame();
Maze maze = game.createMaze();40 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
Intent
Provide an interface for creating families of related or dependentobjects without specifying their concrete classes.
Applicability
a system should be independent of how its products arecreated, composed, and represented
a system should be configured with one of multiple families ofproducts
a family of related product objects is designed to be usedtogether, and you need to enforce this constraint
you want to provide a class library of products, and you wantto reveal just their interfaces, not their implementations.
41 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
Structure
42 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
Consequences
Clients manipulate class instances through their abstractinterfaces, product class names are isolated in theimplementation of the concrete factory, do not appear inclient code.
Makes exchanging product families easy: the class of aconcrete factory appears only once in an application, whereit’s instantiated.
Promotes consistency among products: using objects fromonly one family at a time
43 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
Consequences
Supporting new kinds of products is difficult: theAbstractFactory interface fixes the set of products that can becreated
Relations to other patterns:
Concrete factories are often Singleton
Each class of concrete Product is made at a Factory MethodmakeProduct
If many families of products exist, factories may prefer toclone a product of some family instead of invoking constructor(Prototype)
44 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
A real example of abstract factory: JDBC connection and queryexecution
45 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
A real example of abstract factory: JDBC connection and queryexecution
46 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Abstract factory
String dbasePrefix = "jdbc:";
String dbase = "mysql://localhost:3306/";
// String dbase = "derby:testdb";
String dbaseName = dbasePrefix + dbase;
try {
Class.forName(driverName);
// causes the class to be dynamically loaded (at runtime) and
all its static block executed
connection = DriverManager.getConnection(dbaseName, username,
password);
} catch (Exception e) { // dbase not found?
System.err.println("can’t connect to " + dbaseName + "
because " + e);
connection = DriverManager.getConnection(dbaseName +
";create=true");
}
statement = connection.createStatement();
statement.execute("select * from CUSTOMER");
47 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Motivating example:
same maze creation as before
want to avoid making a factory per type of game, in parallelto mapsites hierarchies
a simpler solution is give to a factory the list of mapsiteobjects of the right subclass
the factory object copies (clones) them to create the maze
48 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
class MazePrototypeFactory {
private Wall prototypeWall;
private Room prototypeRoom;
private Door prototypeDoor;
public Maze MazePrototypeFactory(Wall wall, Room room,
Door door) {
prototypeWall = wall; prototypeRoom = room;
prototypeDoor = door;
}
private Wall makeWall() { return prototypeWall.clone(); }
private Door makeDoor() { return prototypeDoor.clone(); }
private Room makeRoom(MapSite up, MapSite right,
MapSite down, MapSite left) {
Room newRoom = room.clone();
newRoom.initialize(up, right, down, left);
return newRoom;
}
}
49 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
MazePrototypeFactory factory = new MazePrototypeFactory(
new Wall(), new EnchantedRoom(), new DoorNeedingSpell() );
MazeGame game = new MazeGame();
Maze maze = game.createMaze(factory);
Like in Abstract Factory,
class MazeGame {
public Maze createMaze(MazeFactory factory) {
Maze aMaze = new Maze();
Door theDoor = factory.makeDoor();
Room r1 = factory.makeRoom(factory.makeWall(),
factory.makeWall(), factory.makeWall(), theDoor,);
Room r2 = factory.makeRoom(factory.makeWall(), theDoor,
factory.makeWall(), factory.makeWall());
theDoor.setRooms(r1, r2);
return aMaze;
}
}
50 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Second example: traffic simulation (from GRASP patterns,creation expert)
Traffic simulator, with entries, exits and different types ofvehicles.Each type differs in a range of possible values for vehiclelength and maximum speed.When a vehicle is created, these two parameters get a randomvalue within their range.
51 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Entries E1, E2...throw vehicles to lanes, if traffic permits so.
Each entry must create each type of vehicle with its ownprogrammed frequency, like:
Entry Cars Trucks Long trucks
E1 80% 20% 0%E2 50% 30% 20%. . . . . . . . . . . .
52 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Who is prototype factory ? Who are the products ?
53 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Frequencies is aprototype factory whichsupplies vehicles to eachentry. Each Frequencies
object has a list of vehicleprototypes plus percentfrequency,PrototipVehicle.
54 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Client instantiates a Frequencies and assigns it to a Entrada.
55 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Entrada gets some type of vehicle from its particular vehiclefactory.
56 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Not all Car or Track objects are equal: their constructor gets arandom max speed, length etc. within the class range.
57 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Not all Car or Track objects are equal: their constructor gets arandom max speed, length etc. within the class range.Method clona() returns a new object of the same type asprototype, but not exactly equal.
58 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Intent
Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.
Applicability
A system should be independent of how its products are created,composed, and represented; and
the classes to instantiate are specified at run-time
to avoid building a class hierarchy of factories that parallelsthe class hierarchy of products
instances of a class can have one of only a few differentcombinations of state: better create a number of prototypeseach in a state than create and bring to state manually
59 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Prototype
Structure
60 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
Builder
Exercise
61 / 62
Overview Singleton Factory method Abstract factory Prototype Builder You should know. . .
You should know
intent and structure of each pattern
similarity and differences of Factory Method, AbstractFactory: a unique or several product families
similarity and differences of Singleton and Prototype: providesame versus equal object
what each pattern encapsulates
Pattern Aspects that vary
Singleton the sole instance of a classFactory Method subclass of object that is instantiatedAbstract Factory families of product objectsPrototype class of object that is instantiated
62 / 62