Modo de protótipo
A ideia do modo de protótipo é obter um ou mais objetos idênticos ou semelhantes, copiando um objeto existente.
O princípio de funcionamento do modo de protótipo é passar um objeto de protótipo para o objeto a ser criado - o cliente, e o cliente realiza o processo de criação solicitando que o objeto de protótipo se copie. Para entender de acordo com o método de fábrica, o novo objeto de fábrica criado é a própria classe de protótipo.
O processo de criação de alguns objetos no sistema de software é mais complicado e às vezes precisa ser criado com frequência. O modo de protótipo especifica o tipo de objeto a ser criado fornecendo um objeto de protótipo e, em seguida, cria mais objetos do mesmo tipo copiando o objeto de protótipo., Esta é a intenção do padrão de protótipo.
Estrutura do protótipo
A estrutura do protótipo inclui as seguintes funções:
- Protótipo abstrato: declara a interface do próprio clone
- Classe de protótipo concreto (ConcretePrototype): implemente a interface do clone
- Cliente: uma classe abstrata de protótipo é declarada no cliente, e instâncias concretas de objeto de classe de protótipo são clonadas de acordo com as necessidades do cliente
Cópia superficial, cópia profunda
O padrão de protótipo pode ser considerado uma cópia da própria classe, mas essa cópia não é uma cópia do código, mas uma cópia de todos os atributos contidos no objeto. No entanto, diferentes operações de cópia podem produzir duas cópias diferentes, divididas em cópia superficial e cópia profunda.
Cópia superficial
Em uma cópia superficial, se a variável de membro do objeto de protótipo for um tipo de valor (como int, double, char e outros tipos de dados básicos), uma cópia será copiada para o objeto de cópia; se a variável de membro do objeto de protótipo é uma referência / ponteiro, ele será referenciado / O endereço apontado pelo ponteiro é copiado para o objeto de cópia, ou seja, as variáveis membro no objeto protótipo e o objeto de cópia apontam para o mesmo endereço.
Cópia profunda
Em uma cópia profunda, não importa se a variável de membro no objeto de protótipo é um tipo de valor ou um tipo de ponteiro / referência, uma cópia será copiada para o objeto de cópia.
Observe que na cópia profunda, o objeto de ponteiro / referência também será copiado para o objeto de cópia.
Exemplo de padrão de protótipo
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;
}
Observe a diferença entre atribuição de comparação e cópia
Resumo do modo de protótipo
vantagem:
- Quando a criação de uma nova instância de objeto é mais complicada, o modo de protótipo pode simplificar o processo de criação e melhorar a eficiência da criação de objetos;
- Extensível: classes abstratas de protótipo são fornecidas no padrão, e classes de protótipo concretas podem ser estendidas apropriadamente;
- A estrutura de criação é simples: a criação da fábrica é o próprio objeto protótipo
Desvantagens:
- O código de clone profundo é mais complicado;
- Cada classe deve ser equipada com um método clone, e o método está localizado dentro da classe, o que viola o princípio de abertura e fechamento quando modificado;
Ambiente aplicável:
- Quando a criação de uma nova instância de objeto é mais complicada, o modo de protótipo pode simplificar o processo de criação;
- Combinando as vantagens do Artigo 3, é necessário evitar o uso de classes de fábrica hierárquicas para criar objetos hierárquicos, e o objeto de instância da classe tem apenas um ou alguns estados combinados. Ao copiar o objeto de protótipo para obter uma nova instância, é melhor do que usar um construtor.É mais conveniente criar uma nova instância.