//
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