参考Prototype Design Pattern
Factory模式与Prototype模式的异同
the prototype is the object containing clone method used to clone similar objects to it for reducing the number of classes
a solution to these problems
How does one reduce the number of classes that share similar behavoir and relationships
Solution
Define a class to replace all the classes that share similar behavior and relationships. Save instances,called prototypes,of this class. To create an instance of any of the classes replaced, simply clone the desired prototype and modify its attributes
Liabilities(缺点)
- The subclasses of prototype must implement the clone() method. This requires deep-copying if the instances and original must be independent;otherwise, shallow-copying is sufficient
- Implementing clone() may be difficult or impossible if the class is final or there are circular references 循环引用 无法克隆
Example Prototype in Java
- Create a “contract” with clone() and getName() entries
- Design a “registry” that maintains a cache of prototypical objects
- Populate the registry with an initializePrototypes() function
- The registry has a findAndClone() “virtual constructor” that can transform a String into its correct object (it calls clone() which then calls “new”)
- All classes relate themselves to the clone() contract
- Client uses the findAndClone() virtual ctor instead of the “new” operator
package Prototype; interface Prototype { Object clone(); String getName(); }
//1.The clone() contract
interface Command { void execute(); }
class PrototypesModule
{
//2\. "registry" of prototypical objs
private static Prototype[] prototypes = new Prototype[9];
private static int total = 0;
// Adds a feature to the Prototype attribute of the PrototypesModule class
//obj The feature to be added to the Prototype attribute
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() contract
`</pre>
</pre>
<pre>
class This implements Prototype,Command
{
public Object clone()
{
return new This();
}
public String getName()
{
return "This";
}
public void execute()
{
System.out.println("This:execute");
}
}
</pre>
<pre>
class That implements Prototype,Command
{
public Object clone()
{
return new That();
}
public String getName()
{
return "That";
}
public void execute()
{
System.out.println("That:execute");
}
}
</pre>
<pre>
class TheOther implements Prototype,Command
{
public Object clone()
{
return new TheOther();
}
public String getName()
{
return "TheOther";
}
public void execute()
{
System.out.println("TheOther:execute");
}
}
</pre>
<pre>`public class PrototypeDemo {
//3\. Populate the "registry"
public static void initializePrototypes()
{
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;
// 6\. Client does not use "new"
for(int i=0;i<args.length;i++)
{
objects[total] = PrototypesModule.findAndClone(args[i]);
if(objects[total]!=null) total++;
}
for(int i=0;i<total;i++)
{
((Command)objects[i]).execute();
}
}
}