//
Abstract Factory might store a set of Prototypes from which to clone and
//
return product objects. [GOF, p126]
public class FactoryProto
{
interface Xyz { Xyz cloan(); }
static class Tom
implements Xyz {
public Xyz cloan()
{ return new Tom(); }
public String toString() { return "ttt"; }
}
static
class Dick implements Xyz {
public Xyz cloan() { return new Dick(); }
public String toString() { return
"ddd"; }
}
static class Harry implements Xyz {
public Xyz cloan() { return new
Harry(); }
public String
toString() { return "hhh"; }
}
static class Factory
{
private static java.util.Map
prototypes = new java.util.HashMap();
static { prototypes.put( "tom", new Tom() );
prototypes.put(
"dick", new Dick() );
prototypes.put( "harry", new Harry() );
}
public static Xyz makeObject(
String s ) {
return
((Xyz)prototypes.get(s)).cloan();
}
}
public static void main( String[] args ) {
for (int i=0; i < args.length;
i++)
System.out.print(
Factory.makeObject( args[i] ) + "
" );
}}
// D:\Java\patterns> java FactoryProto
tom dick tom harry tom
// ttt
ddd ttt hhh
ttt
// Purpose.
Prototype design pattern
// 1. Create a "contract"
with clone() and getName() entries
// 2. Design a "registry"
that maintains a cache of prototypical objects
// 3. Populate the registry
with an initializePrototypes() function
// 4. The registry has a
findAndClone() "virtual constructor" that can transform
// a String into its correct object (it calls
clone() which then calls "new")
// 5. All classes relate
themselves to the clone() contract
// 6. Client uses the findAndClone()
virtual ctor instead of the "new" operator
interface
Prototype { Object clone(); String
getName(); } // 1. The clone()
interface
Command { void execute(); } //
contract
class PrototypesModule { // 2. "registry" of prototypical
objs
private static Prototype[]
prototypes = new Prototype[9];
private static int total = 0;
public static void addPrototype( Prototype obj ) {
prototypes[total++] = obj;
}
public static Object findAndClone( String name ) { // 4. The "virtual ctor"
for (int i=0; i < total; i++)
if (prototypes[i].getName().equals(
name ))
return
prototypes[i].clone();
System.out.println( name + " not found" );
return null;
} }
// 5. Sign-up for
the clone()
class This implements Prototype, Command { //
contract. Each class
public Object clone() { return new This(); } // calls "new" on itself
public String getName() { return
"This"; } // FOR the client.
public void execute() { System.out.println( "This: execute" );
}
}
class That implements Prototype, Command {
public Object clone() { return new That(); }
public String getName() { return
"That"; }
public
void execute() { System.out.println(
"That: execute" ); }
}
class TheOther implements Prototype,
Command {
public Object
clone() { return new TheOther();
}
public String getName() {
return "TheOther"; }
public void execute() {
System.out.println( "TheOther: execute" ); }
}
public
class PrototypeDemo {
public
static void initializePrototypes() {
// 3. Populate the "registry"
PrototypesModule.addPrototype( new This() );
PrototypesModule.addPrototype( new
That() );
PrototypesModule.addPrototype( new TheOther() );
}
public static void main( String[] args ) {
initializePrototypes();
Object[] objects = new Object[9];
int
total = 0;
for (int i=0; i < args.length; i++)
{ // 6. Client does not use
"new"
objects[total] = PrototypesModule.findAndClone( args[i] );
if (objects[total] != null) total++;
}
for (int i=0; i < total;
i++) ((Command)objects[i]).execute();
}
}
// C:> java PrototypeDemo Garbage This That Nothing
TheOther
// Garbage not found
// Nothing not found
// This:
execute
// That: execute
// TheOther: execute