Dr. Michael Eichberg
Software Engineering
Department of Computer Science
Technische Universität Darmstadt
Introduction to Software Engineering
The Factory Method
Design Pattern
For details see Gamma et al. in “Design Patterns”
|
The GoF Design Patterns
The Factory Method Design Pattern
Example / Motivation
2
Let’s assume we want to develop a framework for
applications that can present multiple documents to the
user (MDI style).
We want to support a wide variety of applications:
Text editors
Word processors
Vector drawing applications
Document Viewers
...
Our framework should - in particular - be able to manage
the documents.
|
The GoF Design Patterns
The Factory Method Design Pattern
Example / Motivation -
Common functionality for handling documents
3
TextMate Nisus Writer Pro
|
The GoF Design Patterns
The Factory Method Design Pattern
Example / Motivation -
Common functionality for handling documents
4
TextMateNisus Writer Pro
(In the following, we focus on the implementation of “New”.)
|
The GoF Design Patterns
The Factory Method Design Pattern
Intent
5
Dene an interface for creating an object, but
let subclasses decide which class to
instantiate.
(Factory Method lets a class defer instantiation
to subclasses.)
|
The GoF Design Patterns
The Factory Method Design Pattern
Example / Motivation -
A Possible Implementation of the Framework
6
public abstract class Document {
public abstract void open();
public abstract void close();
}
public abstract class Application {
private List<Document> docs = new ArrayList<Document>();
public void newDocument() {
Document doc = createDocument();
// the framework manages the documents
docs.add(doc);
doc.open();
}
...
public abstract Document createDocument(); // factory method
}
|
The GoF Design Patterns
The Factory Method Design Pattern
Example / Motivation -
Implementation of an Application Using the Framework
7
public class TextDocument extends Document {
// implementation of the abstract methods
}
public class MyApplication extends Application {
public Document createDocument() {
return new TextDocument();
}
}
|
The GoF Design Patterns
The Factory Method Design Pattern
Example / Motivation -
Class Diagram of an Application Using the Framework
8
open()
close()
save()
Document
TextDocument
createDocument()
newDocument()
Application
createDocument()
MyApplication
docs
|
The GoF Design Patterns
The Factory Method Design Pattern
Structure
9
Product
ConcreteProduct
factoryMethod()
anOperation()
Creator
factoryMethod()
ConcreteCreator
«method»
... factoryMethod()...
|
The GoF Design Patterns
The Factory Method Design Pattern
Participants
10
Product"
… denes the interface of objects the factory method
creates.
ConcreteProduct"
… implements the Product interface.
Creator"
… declares the factory method, which returns an object of
type Product. Creator may also dene a default
implementation of the factory method that returns a
default ConcreteProduct object.
ConcreteCreator"
… overrides the factory method to return an instance of a
ConcreteProduct.
|
The GoF Design Patterns
The Factory Method Design Pattern
Consequences (I)
11
The framework’s code only deals with the Product
interface; therefore it can work with any user-dened
ConcreteProduct class.
Provides a hook for subclasses"
The hook can be used for providing an extended version of
an object.
|
The GoF Design Patterns
The Factory Method Design Pattern
Consequences (II)
12
Connects parallel class hierarchies
Class Name
Collaborator A
Collaborator B
Responsibility A
Responsibility B
Responsibility C
drag()
...
Manipulator
LineManipulator
createManipulator()
Figure
TextManipulator
Client
createManipulator()
Text
createManipulator()
Line
|
The GoF Design Patterns
The Factory Method Design Pattern
Implementation
13
Two major variants:
Creator is abstract
Creator is concrete and provides a reasonable default
implementation
|
The GoF Design Patterns
The Factory Method Design Pattern
Implementation - Parameterized factory methods
14
(E.g. imagine a document previewer which can handle very
dierent types of documents.)
General form:
public abstract class Creator {
public abstract Product createProduct(ProductId pid);
}
Applied to our example:
public abstract class Application {!
public abstract Document createDocument(Type e);!
}
public class MyApplication extends Application {
public Document createDocument(Type e){!
switch(e) {!
case Type.JPEG : return new JPEGDocument();!
case Type.PDF : return new PDFDocument();!
}
} }
|
The GoF Design Patterns
The Factory Method Design Pattern
Implementation - Parameterized factory methods
15
public abstract class Application {
private Class<? extends Document> clazz;
public Application(Class<? extends Document> clazz){
this.clazz = clazz;
}
public abstract Document createDocument(){
return clazz.newInstance();
}
}
It is possible to use Java
reection in a type safe
way.
|
Placeholder
The Factory Method Design Pattern
Related Patterns
Factory Methods are usually called within Te m p l a t e
Methods
Abstract Factory is often implemented with factory
methods
16
Dr. Michael Eichberg
Software Engineering
Department of Computer Science
Technische Universität Darmstadt
Introduction to Software Engineering
The Abstract Factory
Design Pattern
For details see Gamma et al. in “Design Patterns”
|
The GoF Design Patterns
18
How to create families of related classes that
implement a (set of) common interface(s)?
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Motivation / Example Scenario
19
Our goal is to support dierent databases.
Requirements:
The application should support several databases"
(We want to be able to change the database at startup
time.)
We want to support further databases"
(We want to make the implementation unaware of the
specic database(s).)
|
Excursion
Supporting Variety
A result set enables the iteration over the result of an SQL
query.
20
How to provide an interface to
all of these different kinds of
ResultSets?
|
Excursion
A result set enables the iteration over the result of an SQL
query.
Supporting Variety by
Providing a Common Interface
21
A common interface is introduced to
abstract from the concrete classes.
first()
next()
close()
«interface»
java.sql.ResultSet
first()
next()
close()
MySQLResultSet
first()
next()
close()
DB2ResultSet
first()
next()
close()
FirebirdResultSet
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Motivation / Example Scenario
22
To complete the abstraction of the database, one also
needs to create class hierarchies for:
CallableStatements,
PreparedStatements,
Blobs,
The code interacting with the database can now deal
with ResultSets and SQL statements without referring to
the concrete classes, e.g., Firebird-ResultSet
However, we still have to know the concrete
implementation subclass at creation time!
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Issues
23
How can we avoid to know about the concrete product
types at creation time? "
We want to avoid to write:"
PreparedStatement = new FBPreparedStatement();
Hard-coding product types as above makes it impossible to
select a dierent database
Even oine changes are dicult as it is easy to miss one
constructor and end up with FireBird’s
FBPreparedStatement while a DB2 database is used
|
The GoF Design Patterns
Issues -
How can we avoid to know about the concrete product types at
creation time?
24
Swapping Code
Swap in and out dierent les when
compiling for a dierent database
Does neither require subclassing nor
a special creation logic
Trade-os
Application code is completely
unaware of dierent databases
Needs conguration management of
source les
Does not allow dierent databases to
be chosen at startup, e.g., if more
than one is supported
Does not allow multiple databases to
be used at runtime
Solution
// DB2 Version
java.sql.ResultSet
// MySQL Version
java.sql.ResultSet
// MaxDB Version
java.sql.ResultSet
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Structure
25
createProdA()
createProdB()
«interface»
AbstractFactory
createProdA()
createProdB()
ConcreteFactory
«interface»
AbstractProductA
ProductA1 ProductA2
«interface»
AbstractProductB
ProductB1 ProductB2
createProdA()
createProdB()
ConcreteFactory
Client
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Participants
26
AbstractFactory "
… provides an interface for creating products of a family
ConcreteFactory "
… implements the operations to create concrete
products
AbstractProduct"
… declares the interface for concrete products
ConcreteProduct "
... provides an implementation for the product created
by the corresponding ConcreteFactory
Client "
… creates products by calling the ConcreteFactory; "
uses the AbstractProduct interface
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Consequences
27
Abstracts away from concrete products"
(Clients can be ignorant about concrete products they are using,
even at creation time.)
Exchanging product families is easy"
(Changing one line can completely swap the behavior of a whole
product family.)
Ensures consistency among products"
(As family selection is concentrated to one line, one may not
accidentally mix product types.)
Supporting new kinds of products is dicult"
(Adding new products involves changing the abstract factory
and all of its subclasses.)
Creation of objects is non-standard "
(Clients need to know to use the factory rather than a
constructor.)
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Issues -
How can we avoid to know about the concrete product types at
creation time?
28
Factory Class
Group creation functions into a
special "factory" class responsible
for creating the objects to interact
with the database on request.
Has functions like... "
createStatement(), createBlob() and
prepareStatement() "
as part of its interface
Dierent factory subclasses provide
implementations for dierent
databases."
Statement s = connection.createStatement();
Solution
createStatement()
createBlob()
create...()
«interface»
Connection
createStatement()
createBlob()
create...()
MySQLConnection
createStatement()
createBlob()
create...()
DB2Connection
createStatement()
createBlob()
create...()
FirebirdConnection
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Product Creation
29
Creation of database objects is done by accessing the
global variable connection of type Connection (the
“factory)"
Statement = connection.createStatement();
To interact with a dierent database the connection is
initialized dierently:"
connection = "
DriverManager.getConnection("org.postgresql.Driver")"
or"
connection ="
DriverManager.getConnection("org.mysql.Driver")
We can make the initialization value for
DriverManager.getConnection a parameter of the
application
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Applied
30
createStatement()
createBlob()
«interface»
Connection
createStatement()
createBlob()
DB2Connection
«interface»
java.sql.Statement
MySQLStatementDB2Statement FirebirdStatement
«interface»
java.sql.Blob
MySQLBlobDB2Blob FirebirdBlob
|
The GoF Design Patterns
The Abstract Factory Method Design Pattern
Summary
31
Application code can be ignorant about dierent
databases
Only one line of code (or conguration parameter) must
vary to support various databases
Allows dierent databases to be chosen at startup
Enforces creation of consistent product families"
(Prevents FBBlob from being used with a DB2 database.)
Code must follow a new convention for creating
products from a family"
(Instead of using the standard constructor.)
|
The Abstract Factory Method Design Pattern - Applied
32
getNewCashDrawer() : jpos.CashDrawer
getNewCoinDispenser() : jpos.CoinDispenser
...
«interface»
IJavaPOSDevicesFactory
getNewCashDrawer() : jpos.CashDrawer
getNewCoinDispenser() : jpos.CoinDispenser
...
NCRJavaPOSDevicesFactory
getNewCashDrawer() : jpos.CashDrawer
getNewCoinDispenser() : jpos.CoinDispenser
...
NCRJavaPOSDevicesFactory
«method»
{
return new com.ibm.pos.jpos.CashDrawer;
}
«method»
{
return new com.ncr.posdevices.CashDrawer;
}
isDrawerOpened() : boolean
...
«interface»
jpos.CashDrawer
isDrawerOpened() : boolean
...
com.ncr.posdevices.CashDrawer
isDrawerOpened() : boolean
...
com.ibm.pos.jpos.CashDrawer
Example
from the
POS
Domain.
|
The GoF Design Patterns
33
The Abstract Factory Method Design Pattern
Related Patterns
A concrete factory is often a singleton