I understand the design pattern (C ++ implementation)-prototype Pattern)

Source: Internet
Author: User
Solved problems:

Use a prototype instance to specify the type of the object to be created, and copy the prototype to create a new object. In fact, this function is consistent with the c ++ copy constructor. In fact, it is to dynamically extract the status of the current object at runtime.


Class chart structure:

Client role: the customer class initiates a request to create an object.
Prototype role: This is an abstract role, usually implemented by a C # interface or abstract class. This role provides all the interfaces required for the specific prototype class. In C #, the abstract prototype role usually implements the icloneable interface.
Concrete prototype: the object to be copied. This role must implement the interface required by the abstract prototype role.


Example:

For example, refer to the example of wuz316ai1985 resume. Copy the Code as follows:

// Cplusplusprototype. CPP: defines the entry point for the console application. // # include "stdafx. H "# include <iostream> # include <vector> # include <assert. h> using namespace STD; // parent class resume {protected: char * Name; public: Resume () {} virtual ~ Resume () {} virtual resume * clone () {return NULL;} virtual void set (char * n) {} virtual void show () {}}; Class resumea: public resume {public: resumea (const char * Str); // constructor resumea (const resumea & R); // copy constructor ~ Resumea (); // destructor resumea * clone (); // clone, the key is void show (); // display content}; resumea :: resumea (const char * Str) {If (STR = NULL) {name = new char [1]; name [0] = '\ 0 ';} else {name = new char [strlen (STR) + 1]; strcpy (name, STR) ;}} resumea ::~ Resumea () {Delete [] Name;} resumea: resumea (const resumea & R) {name = new char [strlen (R. name) + 1]; strcpy (name, R. name);} resumea * resumea: Clone () {return New resumea (* This);} void resumea: Show () {cout <"resumea Name: "<name <Endl;} class resumeb: public resume {public: resumeb (const char * Str); // const resumeb (const resumeb & R ); // copy the constructor ~ Resumeb (); // destructor resumeb * clone (); // clone, the key is void show (); // display content}; resumeb :: resumeb (const char * Str) {If (STR = NULL) {name = new char [1]; name [0] = '\ 0 ';} else {name = new char [strlen (STR) + 1]; strcpy (name, STR) ;}} resumeb ::~ Resumeb () {Delete [] Name;} resumeb: resumeb (const resumeb & R) {name = new char [strlen (R. name) + 1]; strcpy (name, R. name);} resumeb * resumeb: Clone () {return New resumeb (* This);} void resumeb: Show () {cout <"resumeb Name: "<name <Endl;} int _ tmain (INT argc, _ tchar * argv []) {resume * R1 = new resumea (" "); resume * r2 = new resumeb ("B"); resume * R3 = R1-> clone (); resume * r4 = R2-> clone (); r1-> show (); r2-> show (); // Delete R1, R2 Delete R1; Delete R2; R1 = R2 = NULL; // perform a deep copy on R3, r4 does not affect r3-> show (); R4-> show (); Delete R3; Delete R4; R3 = r4 = NULL; return 0 ;}


Prototype Manager:

Client role: the client class sends a request to the prototype manager to create an object.
Prototype role: This is an abstract role, usually implemented by a C # interface or abstract class. This role provides all the interfaces required for the specific prototype class. In C #, the abstract prototype role usually implements the icloneable interface.
Concrete prototype: the object to be copied. This role must implement the interfaces required by the abstract prototype role.
Prototype manager role: Creates objects of a specific prototype class and records 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> using namespace STD; // parent class resume {protected: char * Name; public: Resume () {} virtual ~ Resume () {} virtual resume * clone () {return NULL;} virtual void set (char * n) {} virtual void show () {}}; Class resumea: public resume {public: resumea (const char * Str); // constructor resumea (const resumea & R); // copy constructor ~ Resumea (); // destructor resumea * clone (); // clone, the key is void show (); // display content}; resumea :: resumea (const char * Str) {If (STR = NULL) {name = new char [1]; name [0] = '\ 0 ';} else {name = new char [strlen (STR) + 1]; strcpy (name, STR) ;}} resumea ::~ Resumea () {Delete [] Name;} resumea: resumea (const resumea & R) {name = new char [strlen (R. name) + 1]; strcpy (name, R. name);} resumea * resumea: Clone () {return New resumea (* This);} void resumea: Show () {cout <"resumea Name: "<name <Endl;} class resumeb: public resume {public: resumeb (const char * Str); // const resumeb (const resumeb & R ); // copy the constructor ~ Resumeb (); // destructor resumeb * clone (); // clone, the key is void show (); // display content}; resumeb :: resumeb (const char * Str) {If (STR = NULL) {name = new char [1]; name [0] = '\ 0 ';} else {name = new char [strlen (STR) + 1]; strcpy (name, STR) ;}} resumeb ::~ Resumeb () {Delete [] Name;} resumeb: resumeb (const resumeb & R) {name = new char [strlen (R. name) + 1]; strcpy (name, R. name);} resumeb * resumeb: Clone () {return New 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 does not affect R3 and R4; r3-> show (); R4-> show (); Delete R3; Delete R4; r3 = r4 = NULL; return 0 ;}


Implementation points:

1. The prototype manager can be dynamically created and destroyed when the number of original types in a system is not fixed.

2. perform the clone operation on. net can use the memberwiseclone () method of the object class to realize the object's superficial copy or the deep copy through serialization. In C ++, it is the role of the copy constructor.

3. The prototype mode is also used to isolate the coupling between the users of class objects and specific types (variable classes). It also requires that these "variable classes" have stable interfaces.


Effect:

1. It hides a specific product class from the customer, thus reducing the number of names that the customer knows.

2. prototype mode allows the customer to integrate a specific product class into the system by registering the prototype instance only. The customer can create and delete the prototype at runtime.

3. The subclass structure is reduced. The prototype mode clones a prototype instead of requesting the factory method to create one. Therefore, it does not need a creater class level parallel to a specific product class.

4. The portotype mode provides the ability to dynamically load new functions for an application. Because prototype is highly independent, it is easy to dynamically load new features without affecting the old system.

5. The product class does not need to have any pre-determined level structure, because the prototype mode applies to any level structure.

6. The main disadvantage of prototype mode is that each class must have a clone method. In addition, this cloning method requires a comprehensive consideration of the functions of the class, which is not very difficult for the brand-new class, but it is not always easy to transform the existing class.


Applicability:

1. When a system should be created, constructed, and expressed independently of its products, the prototype mode is required.

2. When the class to be instantiated is specified at the runtime, such as through dynamic loading

3. To avoid creating a factory class level parallel to the product class level

4. When an instance of a class can only have one of several combinations of different States, it is more convenient to create a prototype of the corresponding number and clone them than to manually instantiate the class with the appropriate state each time.


Lcl_data was originally created in csdn. Net [http://blog.csdn.net/lcl_data/article/details/8764228]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.