1、意图
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2、结构
3、实现
1、使用一个原型管理器
2、实现克隆操作;c++需要使用深拷贝
3、初始化克隆对象;某些需要参数初始化,有些不需要,所有需要一个initialize()操作,以此操作来初始化内部状态
4、代码
完成代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//日志记录器接口:抽象产品
class Logger {
public:
Logger(const char *buf){
this->buf_len = strlen(buf);
this->buf = new char(this->buf_len);
memcpy(this->buf,buf,this->buf_len);
}
Logger(const Logger& other){
buf = new char(other.buf_len);
memcpy(this->buf,other.buf,other.buf_len);
}
virtual ~Logger(){
delete buf;
};
virtual void writeLog() = 0;
virtual Logger* clone() = 0; //通过克隆自己来创建对象
void display(){
if(buf != NULL){
printf("buf = %s\n",buf);
}
}
private:
char* buf;
int buf_len;
};
//数据库日志记录器:具体产品
class DatabaseLogger : public Logger {
public:
DatabaseLogger(const DatabaseLogger& other) : Logger(other){
}
void writeLog() override {
printf("数据库日志记录。");
}
Logger* clone() override {
return new DatabaseLogger(*this);
}
~DatabaseLogger(){}
};
//文件日志记录器:具体产品
class FileLogger : public Logger {
public:
FileLogger(const char *buf) : Logger(buf){}
FileLogger(const FileLogger& other) : Logger(other){
}
void writeLog() override {
display();
printf("文件日志记录。");
}
Logger* clone() override {
return new FileLogger(*this);
}
~FileLogger(){}
};
#include "base.h"
class Client {
public:
Client(Logger* prototype){
this->prototype = prototype;
}
void run() {
Logger* Logger = this->prototype->clone(); //这里还是依赖具体的工厂类,可引入配置文件实现
Logger->writeLog();
}
private:
Logger* prototype;
};
int main()
{
FileLogger logger("123456");
Client client(&logger);
client.run();
}
5、总结
- prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”
- Prototype模式对于“如何创建易变的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象—所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方Clone。
- Prototype模式中的Clone方法可以利用某些框架中的序列化来实现深拷贝。
6、特点
相对于new创建对象,可以独立于类来创建对象
相对于直接赋值,也独立于类来拷贝对象(赋值当时的状态)