What Is the Prototype Pattern?
Use the prototype instance to specify the kind of object to be created, and create a new object by copying these prototypes.
The prototype pattern is a creational design pattern. The prototype pattern allows an object to create another customizable object without knowing any details about how to create it. The working principle is: by passing a prototype object to the object to be created The object to be launched is created by requesting the prototype object to copy itself.
The main problems it faces are: the creation of "some complex structured objects"; due to changes in requirements, these objects often face drastic changes, but they have relatively stable and consistent interfaces.
Because the clone () method is provided in Java to achieve the cloning of objects, the implementation of the prototype mode becomes very simple at once.
Take a spoon as an example:
public abstract class AbstractSpoon implements Cloneable
{
String spoonName;
public void setSpoonName (String spoonName) {this.spoonName = spoonName;}
public String getSpoonName () {return this.spoonName;}
public Object clone ()
{
Object object = null;
try {
object = super.clone ();
} catch (CloneNotSupportedException exception) {
System.err.println ("AbstractSpoon is not Cloneable");
}
return object;
}
}
There are two concrete implementations (ConcretePrototype):
public class SoupSpoon extends AbstractSpoon
{
public SoupSpoon ()
{
setSpoonName ("Soup Spoon");
}
}
Calling prototype mode is simple:
AbstractSpoon spoon = new SoupSpoon ();
AbstractSpoon spoon = new SaladSpoon ();
Of course, you can also combine the factory pattern to create an AbstractSpoon instance.
In Java, the prototype pattern becomes the use of the clone () method. Because of Java's pure object-oriented characteristics, the use of design patterns in Java becomes very natural. This is reflected in many patterns, such as the Iterator traversal pattern.
Prototype mode with prototype manager: Client role: The client class makes a request to the prototype manager to create an object.
Abstract prototype role: This is an abstract role, usually implemented by a C # interface or abstract class. This role gives all the interfaces required by the concrete prototype class. In C #, the abstract prototype role usually implements the ICloneable interface.
Concrete Prototype role: the object being copied. This role needs to implement the interfaces required by the abstract prototype role.
Prototype Manager (Prototype Manager) role: create objects of a specific prototype class, and record each created object.
The code is implemented as follows:
/ CplusplusPrototype.cpp: Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <vector> #include <assert.h> usingnamespace std; // parent class Resume { protected: char * name; public: Resume () {} virtual ~ Resume () {} virtual Resume * Clone () {return NULL;} virtualvoid Set (char * n) {} virtualvoid Show () {}}; class ResumeA : public Resume {public: ResumeA (constchar * str); // Constructor ResumeA (const ResumeA & r); // Copy constructor ~ ResumeA (); // Destructor ResumeA * Clone (); // Clone, the key Where void Show (); // display content}; ResumeA :: ResumeA (constchar * str) {if (str == NULL) {name = newchar ; name [0] = '\ 0';} else { name = newchar [strlen (str) +1]; strcpy (name, str);}} ResumeA :: ~ ResumeA () {delete [] name;} ResumeA :: ResumeA (const ResumeA & r) {name = newchar [strlen (r.name) +1]; strcpy (name, r.name);} ResumeA * ResumeA :: Clone () {returnnew ResumeA (* this);} void ResumeA :: Show () {cout << "ResumeA name : "<< name << endl;} class ResumeB: public Resume {public: ResumeB (constchar * str); // Constructor ResumeB (const ResumeB & r); // Copy constructor ~ ResumeB (); // Destructor ResumeB * Clone (); // Clone, the key is void Show (); // Display content}; ResumeB :: ResumeB (constchar * str) {if (str == NULL) {name = newchar ; name [0] = '\ 0';} else {name = newchar [strlen (str) +1]; strcpy (name, str);}} ResumeB :: ~ ResumeB () {delete [] name;} ResumeB :: ResumeB (const ResumeB & r) {name = newchar [strlen ( r.name) +1]; strcpy (name, r.name);} ResumeB * ResumeB :: Clone () {returnnew ResumeB (* this);} void ResumeB :: Show () {cout << "ResumeB name: "<< name << endl;} class ResumeManager {private: vector <Resume *> mResume; public: ResumeManager () {} void add (Resume * resume) {mResume.push_back (resume);} Resume * get (int index ) const {assert (index> = 0 && index <mResume.size ()); return mResume [index];}}; int _tmain (int argc, _TCHAR * argv []) {ResumeManager * manager = new ResumeManager (); Resume * r1 = new ResumeA ("A"); Resume * r2 = new ResumeB ("B") ; manager-> add (r1); manager-> add (r2); manager-> get (0)-> Show (); manager-> get (1)-> Show (); Resume * r3 = manager-> get (0)-> Clone (); Resume * r4 = manager-> get (1)-> Clone (); // Delete r1, r2 delete r1; delete r2; r1 = r2 = NULL; // Deep copy so No effect on r3, r4 r3-> Show (); r4-> Show (); delete r3; delete r4; r3 = r4 = NULL; return 0;}