Design Patterns:
Creational Patterns II
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
BUILDER PATTERN
Factory Pattern returns one of several
different subclasses depending on the
data passed to in arguments to the
creation methods.
Suppose we don’t want just a computing
algorithm, but a whole different user
interface depending on the data to display.
BUILDER PATTERN
Definition:
Separate the construction of a complex
object from its representation so that the
same construction process can create
different representations.
Design Pattern Lecturer: Zhenyan Ji
BUILDER PATTERN
• Intent
• Defines an instance for creating an
object but letting subclasses decide
which class to instantiate
• Refers to the newly created object
through a common interface
Design Pattern Lecturer: Zhenyan Ji
BUILDER PATTERN
Design Pattern Lecturer: Zhenyan Ji
BUILDER PATTERN
participants
The classes and/or objects participating in
this pattern are:
Builder
specifies an abstract interface for
creating parts of a Product object
Design Pattern Lecturer: Zhenyan Ji
BUILDER PATTERN
ConcreteBuilder
constructs and assembles parts of the
product by implementing the Builder
interface
defines and keeps track of the
representation it creates
provides an interface for retrieving the
product
Design Pattern Lecturer: Zhenyan Ji
Director
constructs an object using the Builder
interface
Design Pattern Lecturer: Zhenyan Ji
THE BUILDER PATTERN
Product
represents the complex object under
construction. ConcreteBuilder builds the
product's internal representation and
defines the process by which it's
assembled
Design Pattern Lecturer: Zhenyan Ji
Software Architecture Lecturer: Zhenyan Ji
Director
Construct ()
for all objects in structure {
builder->BuildPart ()
} ConcreteBuilder1
Builder
buildPart ()
builders
Builder Structure
ConcreteBuilder2
BuildPart()
GetResult() BuildPart()
product2 product1
Design Pattern
Software Architecture Lecturer: Zhenyan JiAP 04/02
Builder - Collaborations
Client creates Director object and
configures it with the desired Builder
object
Director notifies Builder whenever a part of
the product should be built
Builder handles requests from the Director
and adds parts to the product
Client retrieves the product from the
Builder
Design Pattern
Design Pattern Lecturer: Zhenyan Ji
THE BUILDER PATTERN
The Builder Pattern assembles a number
of objects, such as display widgets, in
various ways depending on the data.
Java is the ideal language to implement
Builder patterns.
Java can cleanly separate the data
from the display methods into simple
objects
Design Pattern Lecturer: Zhenyan Ji
An Investment Tracker
Write a program to display a list of stocks, bonds
and mutual funds in each category so we can
select one or more of the investments and plot
their comparative performance.
If there is a large number of funds, use a
multi-choice list box.
If there are 3 or fewer funds, use a set of
check boxes.
Generate an interface that depends on the
number of items to be displayed, and yet have
the same methods for returning the results.
Design Pattern Lecturer: Zhenyan Ji
Example
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Example
abstract class multiChoice {
//This is the abstract base class that the
//listbox and checkbox choice
//panels are derived from
Vector choices; //array of labels
//--------------------------------------------
public multiChoice(Vector choiceList) {
choices = choiceList; //save list
}
Example
//to be implemented in derived classes
abstract public Panel getUI();
//return a Panel of components
abstract public String[] getSelected();
//get list of items
abstract public void clearAll();
//clear selections
}
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Example: Builders
class listboxChoice extends multiChoice
or
class checkBoxChoice extends multiChoice
Design Pattern Lecturer: Zhenyan Ji
Example : Director
create a simple Factory class that decides which
of these two classes to return:
class choiceFactory {
multiChoice ui;
public multiChoice getChoiceUI(Vector choices){
if(choices.size() <=3)
ui = new checkBoxChoice(choices);
else
ui = new listboxChoice(choices);
return ui;
} }
Design Pattern Lecturer: Zhenyan Ji
Example: client-Calling the
Builders
public wealthBuilder() {
super("Wealth Builder"); //frame. title bar
setGUI(); //set up display
buildStockLists(); //create stock lists
choiceFactory cfact; //the factory
}
Example: Calling the Builders
private void setGUI() {
setLayout(new BorderLayout());
Panel p = new Panel();
add("Center", p);
//center contains left and right panels
p.setLayout(new GridLayout(1,2));
//left is list of stocks
stockList= new List(10);
stockList.addItemListener(this);
p.add(stockList);
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
stockList.add("Stocks");
stockList.add("Bonds");
stockList.add("Mutual Funds");
stockList.addItemListener(this);
//Plot button along bottom of display
Panel p1 = new Panel();
p1.setBackground(Color.lightGray);
add("South", p1);
Plot = new Button("Plot");
Plot.setEnabled(false);
//disabled until stock picked
Plot.addActionListener(this);
p1.add(Plot);
//right is empty at first
choicePanel = new Panel();
choicePanel.setBackground(Color.lightGray);
p.add(choicePanel);
}
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
private void stockList_Click() {
Vector v = null;
int index = stockList.getSelectedIndex();
choicePanel.removeAll();
//remove previous ui panel
//this just switches among 3 different
Vectors
//and passes the one you select to the
Builder pattern
switch(index) {
case 0:
v = Stocks; break;
case 1:
v = Bonds; break;
case 2:
v = Mutuals;
}
mchoice = cfact.getChoiceUI(v);
choicePanel.add(mchoice.getUI());
choicePanel.validate();
Plot.setEnabled(true); }
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Example: The List Box Builder
class listboxChoice extends multiChoice {
List list; //investment list goes here
public listboxChoice(Vector choices)
{ super(choices); }
public Panel getUI() {
//create a panel containing a list box
Panel p = new Panel();
list = new List(choices.size()); //list box
list.setMultipleMode(true); //multiple
p.add(list);
//add investments into list box
for (int i=0; i< choices.size(); i++)
list.addItem((String)choices.elementAt(i));
return p; //return the panel
}
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Returns a String array of the investments
the user selects:
public String[] getSelected() {
int count =0;
//count the selected listbox lines
for (int i=0; i < list.getItemCount(); i++ ) {
if (list.isIndexSelected(i))
count++; }
//create a string array big enough for those
//selected
String[] slist = new String[count];
//copy list elements into string array
int j = 0;
for (int i=0; i < list.getItemCount(); i++ ) {
if (list.isIndexSelected(i))
slist[j++] = list.getItem(i); }
return(slist);
}
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Example: CheckBoxBuilder
public checkBoxChoice(Vector choices) {
super(choices);
count = 0;
p = new Panel(); }
public Panel getUI() {
String s;
//create a grid layout 1 column by n rows
p.setLayout(new GridLayout(choices.size(), 1));
//and add labeled check boxes to it
for (int i=0; i< choices.size(); i++) {
s =(String)choices.elementAt(i);
p.add(new Checkbox(s));
count++; }
return p;
}
Applicability
Builder Pattern is used when:
the creation algorithm of a complex
object is independent from the parts that
actually compose the object
the system needs to allow different
representations for the objects that are
being built
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Consequences of the Builder
Pattern
Consequences:
A Builder lets you vary the internal
representation of the product it builds. It
hides the details of how the product is
assembled.
Each specific builder is independent of
the others and of the rest of the program.
This improves modularity and
extensibility.
Each builder constructs the final product
step-by-step, depending on the data.
Consequences of the Builder
Pattern
A builder pattern vs. an abstract factory
pattern
Similarity: Both return classes made up
of a number of methods and objects.
Difference: an abstract factory returns a
family of related classes, a builder
constructs a complex object step by step
depending on the data presented to it.
Design Pattern Lecturer: Zhenyan Ji
Prototype Pattern
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
PROTOTYPE PATTERN
The Protoype pattern is used when
creating an instance of a class is very
time-consuming or complex in some way.
Then you make copies of the original
instance, modifying them as appropriate.
Definition/Intent:
Specifying the kinds of objects to create
using a prototypical instance
creating new objects by copying this
prototype.
PROTOTYPE PATTERN
Design Pattern Lecturer: Zhenyan Ji
PROTOTYPE PATTERN
participants
Prototype
declares an interface for cloning itself
ConcretePrototype
implements an operation for cloning
itself
Design Pattern Lecturer: Zhenyan Ji
PROTOTYPE PATTERN
Client
creates a new object by asking a
prototype to clone itself
Collaborations:
A client asks a prototype to clone Itself.
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Clone method
make a copy of any Java object using the
clone method.
Jobj j1 = (Jobj)j0.clone();
Four restrictions on the clone method:
1.The clone method always returns an
object of type Object. You must cast it to
the actual type of the object you are
cloning.
Clone method
2. It is a protected method and can only be
called from within the same class or the
module that contains that class.
3. You can only clone objects which are
declared to implement the Cloneable
interface.
4. Objects that cannot be cloned throw the
CloneNotSupported Exception.
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Example
Design Pattern Lecturer: Zhenyan Ji
Example
The left-hand list box
Loaded when the program starts.
display the original data.
The names are sorted by sex and then by
time.
The right-hand list box
Loaded when you click on the Clone button.
Display the sorted data in the cloned class.
The names are sorted only by time.
Design Pattern Lecturer: Zhenyan Ji
Example: prototype
public class SwimData implements Cloneable {
public Object clone() {
try{
return super.clone();
} catch(Exception e) {
System.out.println(e.getMessage());
return null;
}
}
}
Design Pattern Lecturer: Zhenyan Ji
Example: prototype
Do the typecasting within the method.
public SwimData cloneMe() {
try{
return (SwimData)super.clone();
} catch(Exception e) {
System.out.println(e.getMessage());
return null;
}
}
Design Pattern Lecturer: Zhenyan Ji
Example
class Swimmer {
String name;
int age;
String club;
float time;
boolean female;
Design Pattern Lecturer: Zhenyan Ji
Example: prototype
public class SwimData implements
Cloneable {
Vector swimmers;
public SwimData(String filename) {
String s = "";
swimmers = new Vector();
//open data file
InputFile f = new InputFile(filename);
s= f.readLine();
//read in and parse each line
while(s != null) {
swimmers.addElement(new
Swimmer(s));
s= f.readLine();
}
f.close(); }
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Example
swList.removeAll(); //clear list
for (int i = 0; i < sdata.size(); i++) {
sw = sdata.getSwimmer(i);
swList.addItem(sw.getName()+"
"+sw.getTime());
}
Design Pattern Lecturer: Zhenyan Ji
Example
sxdata = (SwimData)sdata.clone();
sxdata.sortByTime(); //re-sort
cloneList.removeAll(); //clear list
//now display sorted values from clone
for(int i=0; i< sxdata.size(); i++) {
sw = sxdata.getSwimmer(i);
cloneList.addItem(sw.getName()+"
"+sw.getTime());
}
Design Pattern Lecturer: Zhenyan Ji
Shallow Copy
Clone method in Java is a shallow copy of
the original class.
Design Pattern Lecturer: Zhenyan Ji
Deep Copy
Using the serializable interface to make a
deep copy of the data.
A serializable class can be written out as
a stream of bytes and those bytes can
be read back to reconstruct the class.
Write the bytes of the object to an output
stream and reread them to create a
complete data copy of that instance of a
class.
Deep Copy
Deep Copy allows to copy an instance of a
class of any complexity and have data that
is completely independent between the
two copies.
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
Deep Copy
public class SwimData implements
Cloneable, Serializable
class Swimmer implements Serializable
public Object deepClone() {
try{
ByteArrayOutputStream b = new
ByteArrayOutputStream();
ObjectOutputStream ut = new
ObjectOutputStream(b);
out.writeObject(this);
Deep Copy
ByteArrayInputStream bIn = new
ByteArrayInputStream(b.toByteArray());
ObjectInputStream i = new
ObjectInputStream(bIn);
return (oi.readObject());
} catch (Exception e) {
System.out.println("exception:"+e.getM
essage());
return null; }
}
Design Pattern Lecturer: Zhenyan Ji
Applicability
Use Prototype Pattern when a system
should be independent of how its products
are created, composed, and represented,
and:
Classes to be instantiated are specified
at run-time
Avoiding the creation of a factory
hierarchy is needed
It is more convenient to copy an existing
instance than to create a new one.
Design Pattern Lecturer: Zhenyan Ji
Design Pattern Lecturer: Zhenyan Ji
SUMMARY OF CREATIONAL
PATTERNS
The Factory Pattern is used to choose
and return an instance of a class from a
number of similar classes based on data
you provide to the factory.
The Abstract Factory Pattern is used to
return one of several groups of classes. In
some cases it actually returns a Factory
for that group of classes.
The Builder Pattern assembles a number of
objects to make a new object, based on the data
with which it is presented. Frequently, the choice
of which way the objects are assembled is
achieved using a Factory.
The Prototype Pattern copies or clones an
existing class rather than creating a new
instance when creating new instances is more
expensive.
The Singleton Pattern is a pattern that insures
there is one and only one instance of an object,
and that it is possible to obtain global access to
that one instance.
Design Pattern Lecturer: Zhenyan Ji