Design pattern (6) Prototype pattern

Prototype mode

The idea of ​​the prototype mode is to obtain one or more identical or similar objects by copying an existing object.

The working principle of the prototype mode is to pass a prototype object to the object to be created-the client, and the client realizes the creation process by requesting the prototype object to copy itself. To understand according to the factory method, the new factory object created is the prototype class itself.

The creation process of some objects in the software system is more complicated and sometimes needs to be created frequently. The prototype mode specifies the type of object to be created by giving a prototype object, and then creates more objects of the same type by copying the prototype object. , This is the intent of the prototype pattern.

Prototype structure

The prototype structure includes the following roles:

  • Abstract Prototype: declares the interface of clone itself
  • Concrete prototype class (ConcretePrototype): implement the clone interface
  • Client: An abstract prototype class is declared in the client, and concrete prototype class object instances are cloned according to customer needs
    Insert picture description here

Shallow copy, deep copy

The prototype pattern can be said to be a copy of the class itself, but this copy is not a copy of the code, but a copy of all the attributes contained in the object. However, different copy operations may produce two different copies, divided into shallow copy and deep copy.

Shallow copy

In shallow copy, if the member variable of the prototype object is a value type (such as int, double, char and other basic data types), a copy will be copied to the copy object; if the member variable of the prototype object is a reference/pointer, it will be referenced/ The address pointed to by the pointer is copied to the copy object, that is, the member variables in the prototype object and the copy object point to the same address.

Deep copy

In a deep copy, no matter whether the member variable in the prototype object is a value type or a pointer/reference type, it will be copied to the copy object.
Note that in the deep copy, the pointer/reference object will also be copied to the copy object.

Prototype pattern example

prototype_pattern.h

#include <iostream>
#include <string.h>

using namespace std;

//work model类
class WorkModel
{
    
    
public:
	string modelName;

	void setWorkModelName(string iName){
    
    
		this->modelName = iName;
	}
};

//抽象原型类PrototypeWork
class PrototypeWork
{
    
    
public:
	PrototypeWork(){
    
    }
	virtual PrototypeWork *clone() = 0;

private:
	
};

//具体原型类ConcreteWork
class ConcreteWork :public PrototypeWork
{
    
    
public:
	ConcreteWork(){
    
    }

	ConcreteWork(string iName, int iIdNum, string modelName){
    
    
		this->name = iName;
		this->idNum = iIdNum;
		this->workModel = new WorkModel();
		this->workModel->setWorkModelName(modelName);
	}
	
	ConcreteWork *clone(){
    
    
		ConcreteWork *work = new ConcreteWork();
		work->setName(this->name);
		work->setIdNum(this->idNum);
		work->workModel = this->workModel;

		return work;
	}

	void setName(string iName){
    
    
		this->name = iName;
	}

	void setIdNum(int iIdNum){
    
    
		this->idNum = iIdNum;
	}

	void setModel(WorkModel *iWorkModel){
    
    
		this->workModel = iWorkModel;
	}

	//打印work信息
	void printWorkInfo(){
    
    
		cout << "name:\t" << this->name << endl;
		cout << "idNum:\t" << this->idNum << endl;
		cout << "modelName:\t" << this->workModel->modelName << endl;
	}

// private:
	string name;
	int idNum;
	WorkModel *workModel;
};

prototype_pattern.cpp

#include "prototype_pattern.h"

int main()
{
    
    
// 赋值
#if 0
    ConcreteWork *BasicWork = new ConcreteWork("basic", 1001, "basic_Model");
	cout << "\nBasic Work:\n";
    BasicWork->printWorkInfo();

	ConcreteWork *CopyWork = BasicWork;
	cout << "\nCopy Work:\n";
    CopyWork->printWorkInfo();

	cout << "\nCopy 完成后,记得跟新WorkName,Num以及ModelName!\n";
	CopyWork->setName("CopyWork");
	CopyWork->setIdNum(1002);
	WorkModel *CopyModel = new WorkModel();
	CopyModel->setWorkModelName("Copy_Model");
	CopyWork->setModel(CopyModel);

	cout << "\nBasic Work \n";
	BasicWork->printWorkInfo();
	cout << "\nCopy Work \n";
	CopyWork->printWorkInfo();

	delete CopyModel;
	delete CopyWork;
	
#else 
// 克隆
	ConcreteWork *BasicWork = new ConcreteWork("basic", 1001, "Basic_Model");
	cout << "\nBasic Work:\n";
    BasicWork->printWorkInfo();

	ConcreteWork *CopyWork = BasicWork->clone();
	cout << "\nCopy Work:\n";
    CopyWork->printWorkInfo();

	cout << "\nCopy 完成后,记得跟新WorkName,Num以及ModelName !\n";
	CopyWork->setName("CopyWork");
	CopyWork->setIdNum(1002);
	WorkModel *CopyModel = new WorkModel();
	CopyModel->setWorkModelName("Copy_Model");
	CopyWork->setModel(CopyModel);

	//检查下是否改对了
	cout << "\nBasic Work \n";
	BasicWork->printWorkInfo();
	cout << "\nCopy Work \n";
	CopyWork->printWorkInfo();

    delete BasicWork;
	delete CopyModel;
	delete CopyWork;

#endif

	return 0;
}

Note the difference between comparison assignment and copy

Summary of prototype mode

advantage:

  • When creating a new object instance is more complicated, the prototype mode can simplify the creation process and improve the efficiency of creating objects;
  • Extensible: Abstract prototype classes are provided in the pattern, and concrete prototype classes can be extended appropriately;
  • The creation structure is simple: the creation of the factory is the prototype object itself

Disadvantages:

  • Deep clone code is more complicated;
  • Each class must be equipped with a clone method, and the method is located inside the class, which violates the principle of opening and closing when modified;

Applicable environment:

  • When creating a new object instance is more complicated, the prototype mode can simplify the creation process;
  • Combining the advantages of Article 3, it is necessary to avoid the use of hierarchical factory classes to create hierarchical objects, and the instance object of the class has only one or a few combined states. By copying the prototype object to obtain a new instance, it is better than by using a constructor. It is more convenient to create a new instance.

Guess you like

Origin blog.csdn.net/qq_24649627/article/details/115209168