1 1.Introduction 2.Factory Method 3.Abstract Factory 4.Prototype 5.Builder 6.Singleton.
-
Upload
theresa-wilkins -
Category
Documents
-
view
236 -
download
0
Transcript of 1 1.Introduction 2.Factory Method 3.Abstract Factory 4.Prototype 5.Builder 6.Singleton.
2
The Gang Of Four catalogue
Purpose
Sco
pe
Class
Object
Creational Structural Behavioral
Factory Method
Abstract Factory
Builder
Prototype
Singleton
Adapter
Adapter
Bridge
Composite
Decorator
Façade
Flyweight
Proxy
Interpreter
Template Method
Chain of resp.
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor
3
Creational Patterns
Common objective : - abstract object creation process (how, when, by whom)- avoid hard coding concrete types in client code
Fundamental problem : “weaknesses of constructors”• fixed return type (= DYNAMIC type)• not inherited -> no polymorphism possible
Solutions :- use inheritance to decide run time type
(class creational – factory method)- delegate creation process to object –
run time types depend on object type and behavior(object creational)
4
Creational PatternsNo constructor polymorphism
Desired dependency
Unwanted dependency
Solutions :Factory methodAbstract FactoryPrototype
//…Common c = new A();Common d = new B();// …
5
Motivation• support pluggable GUI look and feel• abstract look and feel code from client (to promote cross-platform portability)
BUT :• client must hardcode concrete object types
(can not program to top level classes !)• product families can get mixed !
6
Motivation
class Client {
public Client() {// …Button b = new XPButton();Window w = new XPWindow();Button c = new AppleButton();// …
}}
Constructor weaknesses :• fixed return type (= DYNAMIC type)• not inherited -> no polymorphism possible
Solution : create constructor-like method (the “factory method”)
8
The solutionabstract class Client {
private Button b,c;
private Window w;
public Client() {
// …
b = createButton();
w = createWindow();
c = createButton();
// …
}
public abstract Button createButton(); // factory method
public abstract Window createWindow(); // factory method
}
class AppleClient extends Client {
public AppleClient() {super();}
public Window createWindow() {return new AppleWindow();}
public Button createButton() {return new AppleButton();}
}
class Test {
public static void main(String[] args) {
Client c=new AppleClient();
}
}
10
Example : A bike raceclass Bicycle {
protected String trademark;
protected int ID;
public Bicycle(String s,int i) {trademark=s;ID=i;}
public String toString() {
return ""+trademark+" : "+ID;
}
}
class StandardBicycle extends Bicycle {
public StandardBicycle(String t,int i) {super(t,i);}
public String toString() {
return "Standard Bike : "+super.toString();
}
}
class Tandem extends Bicycle {
public Tandem(String t,int i) {super(t,i);}
public String toString() {
return "Tandem : "+super.toString();
}
}
11
Example : A bike raceclass Participant {
protected String name;
public Participant(String s) {name=s;}
public String toString() {
return name;
}
}
class StandardParticipant extends Participant{
public StandardParticipant(String s) {super(s);}
public String toString() {
return "Standard Participant : "+super.toString();
}
}
class TandemParticipant extends Participant{
public TandemParticipant(String s) {super(s);}
public String toString() {
return "Tandem Participant : "+super.toString();
}
}
12
Example : A bike raceabstract class Race {
Bicycle[] b;
Participant[] p;
public Race(String[] tm,String[] n) {
b=new Bicycle[tm.length];
p=new Participant[tm.length];
for(int i=0;i<b.length;i++) {
b[i]=createBicycle(tm[i],i);
p[i]=createParticipant(n[i]);
}
}
public String toString() {
String r="The race :\n";
for(int i=0;i<b.length;i++)
r+="\t"+b[i]+" -> "+p[i]+"\n";
return r;
}
public Participant doRace() {
return p[(int)(Math.random()*(b.length))];
}
public abstract Bicycle createBicycle(String s,int i);
public abstract Participant createParticipant(String s);
}
NO CONSTRUCTORS HERE !
Factory methods
13
Example : A bike raceclass StandardRace extends Race {
public StandardRace(String[] tm,String[] n) {super(tm,n);}
public Bicycle createBicycle(String s,int i) {
return new StandardBicycle(s,i);
}
public Participant createParticipant(String s) {
return new StandardParticipant(s);
}
}
class TandemRace extends Race {
public TandemRace(String[] tm,String[] n) {super(tm,n);}
public Bicycle createBicycle(String s,int i) {
return new Tandem(s,i);
}
public Participant createParticipant(String s) {
return new TandemParticipant(s);
}
}
14
Example : A bike raceclass Test {
public static void main(String[] args) {
String[] tm={"Eddy M.","Bike Inc.","Wheels2Wheels","Eddy M."};
String[] n={"John","Mary","Eddy","Fred"};
Race r=new TandemRace(tm,n);
// or : Race r=new StandardRace(tm,n);
System.out.println(r);
System.out.println("START ...");
System.out.println("The winner is : "+r.doRace());
}
}
15
Notes
• when difficult to anticipate what type of objects to create
• when subclass must specify object type to create
Applicability
Consequences
• allows for hooks in the application through subclassing
• allows to connect parallel class hierarchies
Factory methods are often used in• other creational patterns• Template Method pattern
17
The solution
class Client {GUIFactory f;public Cient(GUIFactory ff) {
f=ff;// …Button b = f.createButton();Window w = f.createWindow();Button c = f.createButton();// do something useful
}}
class Test {public static void main(String[] args) {
Client c=new Client(new XPGUIFactory());}
} • version for XP platform• can be changed (check at runtime which factories are available)
19
Example : A bike raceinterface RaceFactory {
Bicycle createBicycle(String s,int ID);
Participant createParticipant(String s);
}
class StandardRaceFactory implements RaceFactory {
public Bicycle createBicycle(String s,int ID) {
return new StandardBicycle(s,ID);
}
public Participant createParticipant(String s) {
return new StandardParticipant(s);
}
}
class TandemRaceFactory implements RaceFactory {
public Bicycle createBicycle(String s,int ID) {
return new Tandem(s,ID);
}
public Participant createParticipant(String s) {
return new TandemParticipant(s);
}
}
20
Example : A bike raceclass Race {
RaceFactory f;
Bicycle[] b;
Participant[] p;
public Race(RaceFactory ff,String[] tm,String[] n) {
f=ff;
b=new Bicycle[tm.length];
p=new Participant[tm.length];
for(int i=0;i<b.length;i++) {
b[i]=f.createBicycle(tm[i],i);
p[i]=f.createParticipant(n[i]);
}
}
public String toString() {
String r="The race :\n";
for(int i=0;i<b.length;i++)
r+="\t"+b[i]+" -> "+p[i]+"\n";
return r;
}
public Participant doRace() {
return p[(int)(Math.random()*(b.length))];
}
}
21
Example : A bike race
class Test {
public static void main(String[] args) {
RaceFactory f=new TandemRaceFactory();
// or : RaceFactory f=new StandardRaceFactory();
String[] tm={"Eddy M.","Bike Inc.","Wheels2Wheels","Eddy M."};
String[] n={"John","Mary","Eddy","Fred"};
Race r=new Race(f,tm,n);
System.out.println(r);
System.out.println("START ...");
System.out.println("The winner is : "+r.doRace());
}
}
22
Notes
• when independency of product creation, composition and representation is needed
• when system should be configured with different product families
• when enforcing constraints on using only products in family
Applicability
Consequences
• concrete product classes shielded from client application code
• easy to change between product families, and to enforce consistency
• difficult to add new products
Creation of abstract factory object itself often implemented as a Singleton !
24
The solutionclass Client {
Button protoButton;Window protoWindow;Button b,c;Window w;public Cient(Button bb,Window ww) {
protoButton=bb;protoWindow=ww;// …b = protoButton.clone();w = protoWindow.clone();c = protoButton.clone();// do something useful
}}class Test {
public static void main(String[] args) {Client c=new Client(new XPWindow(), new AppleButton());
}}
26
Example : A bike raceclass Bicycle {
protected String trademark;
protected int ID;
public Bicycle(String s,int i) {trademark=s;ID=i;}
public String toString() {return ""+trademark+" : "+ID;}
public Bicycle mclone() {return new Bicycle(trademark,ID);}
public void setTrademark(String tm) {trademark=tm;}
public void setID(int i) {ID=i;}
}
class StandardBicycle extends Bicycle {
public StandardBicycle(String t,int i) {super(t,i);}
public String toString() {return "Standard Bike : "+super.toString();}
public Bicycle mclone() {return new StandardBicycle(trademark,ID);}
}
class Tandem extends Bicycle {
public Tandem(String t,int i) {super(t,i);}
public String toString() {return "Tandem : "+super.toString();}
public Bicycle mclone() {return new Tandem(trademark,ID);}
}
27
Example : A bike raceclass Participant {
protected String name;
public Participant(String s) {name=s;}
public String toString() {return name;}
public Participant mclone() {return new Participant(name);}
public void setName(String s) {name=s;}
}
class StandardParticipant extends Participant{
public StandardParticipant(String s) {super(s);}
public String toString() {return "Standard Participant : "+super.toString();}
public Participant mclone() {return new StandardParticipant(name);}
}
class TandemParticipant extends Participant{
protected String second;
public TandemParticipant(String s1,String s2) {super(s1);second=s2;}
public String toString() {
return "Tandem Participant : "+super.toString()+" + "+second;
}
public void setSecond(String s) {second=s;}
public Participant mclone() {return new TandemParticipant(name,second);}
}
28
Example : A bike raceclass Race {
private Bicycle[] b;
private Participant[] p;
private Bicycle pB;
private Participant pP;public Race(Bicycle bb,Participant pp,String[] tm,String[] n) {
pB=bb;
pP=pp;
b=new Bicycle[tm.length];
p=new Participant[tm.length];
for(int i=0;i<b.length;i++) {
b[i]=pB.mclone();b[i].setTrademark(tm[i]);b[i].setID(i);
p[i]=pP.mclone();p[i].setName(n[i]);
// can not set state for tandem participant !
}
}
public String toString() {
String r="The race :\n";
for(int i=0;i<b.length;i++)
r+="\t"+b[i]+" -> "+p[i]+"\n";
return r;
}
public Participant doRace() {
return p[(int)(Math.random()*(b.length))];
}
}
29
Example : A bike raceclass Test {
public static void main(String[] args) {
String[] tm={"Eddy M.","Bike Inc.","Wheels2Wheels","Eddy M."};
String[] n={"John","Mary","Eddy","Fred"};
// Race r=new Race(new StandardBicycle("Dummy",0),new StandardParticipant("Dummy"),tm,n);
Race r=new Race(new Tandem("Dummy",0),new TandemParticipant("X","Y"),tm,n);
System.out.println(r);
System.out.println("START ...");
System.out.println("The winner is : "+r.doRace());
}
} The race : Tandem : Eddy M. : 0 -> Tandem Participant : John + Y Tandem : Bike Inc. : 1 -> Tandem Participant : Mary + Y Tandem : Wheels2Wheels : 2 -> Tandem Participant : Eddy + Y Tandem : Eddy M. : 3 -> Tandem Participant : Fred + Y
START ...The winner is : Tandem Participant : Eddy + Y
30
Java cloningJAVA • root type Object declares : public Object clone() for copying purposes …
• Java approach : - override clone() method - requires DOWNCAST to actual type !
class Tandem extends Bicycle {
public Tandem(String t,int i) {super(t,i);}
public String toString() {return "Tandem : "+super.toString(); }
public Object clone() {return new Tandem(trademark,ID);}
}
class Race {
private Bicycle[] b;private Participant[] p;
private Bicycle pB;private Participant pP;
public Race(Bicycle bb,Participant pp,String[] tm,String[] n) {
pB=bb;pP=pp;
b=new Bicycle[tm.length];p=new Participant[tm.length];
for(int i=0;i<b.length;i++) {
b[i]=(Bicycle)(pB.clone());b[i].setTrademark(tm[i]);b[i].setID(i);
p[i]=(Participant)(pP.clone());p[i].setName(n[i]); }
} //…
}
31
Notes
• run-time specification of classes (e.g. dynamic loading application)
• avoid to construct factory hierarchy
• primarily when not too much variation in state info is required
Applicability
Implementation issues
• clone() should implement a deep copy (to be safe)
• a prototype manager can be used to hold all possible prototypes
• factory object (in Abstract Factory & Builder patterns) can be configured using prototypes
33
The solutionabstract class Client {
GUI g;
public Client(Builder bb) {
director=new Director(bb);
director.construct();
g=bb.getResult();
// …
}
}
class Director {
private Builder b;
public Director(Builder bb) {b=bb;}
public void construct() {
b.buildButton();
b.buildWindow();
//…
}
}
class Test {
public static void main(String[] args) {
Client c=new AppleClient(new AppleBuilder());
}
}
35
Example : A bike raceclass NMDirector {
private int n;
private int m;
private Builder b;
public NMDirector(Builder bb,int nn,int mm) {
b=bb;n=nn;m=mm;
}
public void construct() {
b.initPartX(n);
b.initPartY(m);
for(int i=0;i<n;i++) b.buildPartX(i);
for(int i=0;i<m;i++) b.buildPartY(i);
}
}
abstract class Builder {
abstract void buildPartX(int i);
abstract void buildPartY(int i);
abstract void initPartX(int n);
abstract void initPartY(int n);
}
36
Example : A bike raceclass StandardRaceBuilder extends Builder {
private Race r=new Race();
private String[] tm,n;
public StandardRaceBuilder(String[] trade,String[] name) {
tm=trade;n=name;
}
public void initPartX(int n) {r.setBicycleSize(n);}
public void initPartY(int n) {r.setParticipantSize(n);}
public void buildPartX(int i) {r.setBicycle(new StandardBicycle(tm[i],i),i);}
public void buildPartY(int i) {r.setParticipant(new StandardParticipant(n[i]),i);}
public Race getResult() {return r;}
}
class TandemRaceBuilder extends Builder {
private Race r=new Race();
private String[] tm,n;
public TandemRaceBuilder(String[] trade,String[] name) {
tm=trade;n=name;
}
public void initPartX(int n) {r.setBicycleSize(n);}
public void initPartY(int n) {r.setParticipantSize(n);}
public void buildPartX(int i) {r.setBicycle(new Tandem(tm[i],i),i);}
public void buildPartY(int i) {r.setParticipant(new TandemParticipant(n[i]),i);}
public Race getResult() {return r;}
}
37
Example : A bike raceclass Race {
Bicycle[] b;Participant[] p;
public String toString() {
String r="The race :\n";
for(int i=0;i<b.length;i++) r+="\t"+b[i]+" -> "+p[i]+"\n";
return r;
}
public Participant doRace() {return p[(int)(Math.random()*p.length)];}
public void setBicycleSize(int n) {b=new Bicycle[n];}
public void setParticipantSize(int n) {p=new Participant[n];}
public void setBicycle(Bicycle bike,int i) {b[i]=bike;}
public void setParticipant(Participant part,int i) {p[i]=part;}
}
class Test {
public static void main(String[] args) {
String[] tm={"Eddy M.","Bike Inc.","Wheels2Wheels","Eddy M."};
String[] n={"John","Mary","Eddy","Fred"};
//StandardRaceBuilder b=new StandardRaceBuilder(tm,n);
TandemRaceBuilder b=new TandemRaceBuilder(tm,n);
NMDirector d=new NMDirector(b,tm.length,n.length);
d.construct();
Race r=b.getResult();
System.out.println(r);System.out.println("START ...");
System.out.println("The winner is : "+r.doRace());
}
}
38
Example : A bike raceclass CountingBuilder extends Builder {
private int b;
private int p;
private String[] tm,n;
public CountingBuilder(String[] trade,String[] name) {
tm=trade;n=name;
}
public void initPartX(int n) {b=0;}
public void initPartY(int n) {p=0;}
public void buildPartX(int i) {b++;}
public void buildPartY(int i) {p++;}
public int getResult() {return (b+p);};
}
class Test {
public static void main(String[] args) {
String[] tm={"Eddy M.","Bike Inc.","Wheels2Wheels","Eddy M."};
String[] n={"John","Mary","Eddy","Fred"};
CountingBuilder c=new CountingBuilder(tm,n);
NMDirector dc=new NMDirector(c,tm.length,n.length);
dc.construct();
System.out.println("The result is : "+c.getResult());
}
}
39
Notes
• algorithm for creating complex object independent of the individual parts (typical application : parsers)
• different representations of same object to be supported by the construction process
Applicability
Main usage
• parsing (XML), formatting, compilers