电子购物网站的设计与实现,柳州网站建设多少钱,wordpress主题手机,微信接口开发平台文章目录原型模式简介原型模式结构关于克隆方法#xff1a;浅拷贝/深拷贝原型模式代码实例定义原型类和克隆方法客户端使用代码示例示例一#xff1a;浅拷贝示例二#xff1a;深拷贝原型模式总结开闭原则代码仓库原型模式#xff1a;用原型实例指定创建对象的种类#xff…
文章目录原型模式简介原型模式结构关于克隆方法浅拷贝/深拷贝原型模式代码实例定义原型类和克隆方法客户端使用代码示例示例一浅拷贝示例二深拷贝原型模式总结开闭原则代码仓库原型模式用原型实例指定创建对象的种类并且通过拷贝这些原型创建新的对象。
定义看起来有点绕口不妨简单的理解为原型模式就是用来克隆对象的。
举个例子比如有一天周杰伦到奶茶店点了一份不加冰的原味奶茶你说我是周杰伦的忠实粉我也要一份跟周杰伦一样的。
即便Jungle读书少Jungle也清晰地记得中学生物课本上提到过的克隆羊“多利”。虽然多利寿命不长但它的出现对“克隆Clone”技术意义重大。克隆直观说就是从原有生物体上取体细胞然后无性繁殖出有完全相同基因的个体或种群。这么说来中国的克隆技术其实是世界领先的因为孙悟空拔一根毫毛变出许多一模一样的孙悟空的传说本质上就是克隆而本文将要介绍的原型模式将克隆技术应用到了软件设计层面。
原型模式简介
原型模式通过复制一个已有对象来获取更多相同或者相似的对象。原型模式定义如下
使用原型实例指定待创建对象的类型并且通过复制这个原型来创建新的对象。
原型模式的工作原理是将一个原型对象传给要发动创建的对象即客户端对象这个要发动创建的对象通过请求原型对象复制自己来实现创建过程。从工厂方法角度而言创建新对象的工厂就是原型类自己。软件系统中有些对象的创建过程比较复杂且有时需要频繁创建原型模式通过给出一个原型对象来指明所要创建的对象的类型然后用复制这个原型对象的办法创建出更多同类型的对象这就是原型模式的意图所在。
原型模式结构 关于克隆方法浅拷贝/深拷贝 原型模式代码实例
明天就是周一了Jungle又陷入了苦恼中因为作业还没完成。于是Jungle想拿着哥哥Single的作业来抄一份。虽然抄袭作业并不好但是边抄边学借鉴一下也是可以的。于是乎Jungle开始动起手来……
作业包含几个部分姓名name、学号idNum、模型(workModel)。首先定义一个workModel类
// work model类
// 作为复杂的成员对象供ConcreteWork引用。
class WorkModel {
public:std::string modelName;WorkModel() : modelName() {}WorkModel(const std::string iName) : modelName(iName) {}void setWorkModelName(const std::string iName) {this-modelName iName;}std::string getWorkModelName() const {return modelName;}// 深拷贝构造函数// 深拷贝构造函数防止多个对象共享同一个内存避免浅拷贝问题。// std::string 本身已经重载了拷贝构造函数和赋值运算符实现了深拷贝的语义。WorkModel(const WorkModel other) : modelName(other.modelName) {}
}; 该实例UML图如下
定义原型类和克隆方法
// 抽象原型类PrototypeWork
// 定义抽象接口clone()具体原型类必须实现该方法。
class PrototypeWork {
public:PrototypeWork() {}virtual ~PrototypeWork() {}virtual PrototypeWork* clone() 0;virtual void printWorkInfo() const 0;
};// 具体原型类PrototypeWork
class ConcreteWork: public PrototypeWork {
public:ConcreteWork(const string iName, int iIdNum, const string modelName): name(iName), idNum(iIdNum), workModel(new WorkModel(modelName)) {}// 深拷贝构造函数ConcreteWork(const ConcreteWork other): name(other.name), idNum(other.idNum), workModel(new WorkModel(*other.workModel)) {}// 深拷贝赋值运算符// ConcreteWork operator(const ConcreteWork other) {// if (this ! other) {// name other.name;// idNum other.idNum;// delete workModel;// workModel new WorkModel(*other.workModel);// }// return *this;// }// 克隆接口实现返回深拷贝PrototypeWork* clone() override {return new ConcreteWork(*this);}~ConcreteWork() {delete workModel;}// 打印work信息void printWorkInfo() const override {std::cout Name: name std::endl;std::cout IdNum: idNum std::endl;std::cout ModelName: workModel-getWorkModelName() std::endl;}// 新增set方法void setName(const std::string newName) {name newName;}void setIdNum(int newIdNum) {idNum newIdNum;}void setModel(WorkModel* newModel) {if (workModel ! nullptr) {delete workModel;}workModel newModel;}// 新增get方法std::string getName() const {return name;}int getIdNum() const {return idNum;}WorkModel* getModel() const {return workModel;}private:string name;int idNum;WorkModel* workModel;
};客户端使用代码示例
示例一浅拷贝
#include PrototypePattern.hint main() {
// #if 0
// // 下面的代码将不会被编译也不会执行ConcreteWork *singleWork new ConcreteWork(Single,1001,Single_Model);printf(\nSingle的作业\n);singleWork-printWorkInfo();printf(\njungle直接抄作业……\n);ConcreteWork *jungleWork singleWork;printf(\nJungle的作业\n);jungleWork-printWorkInfo();// 抄完改名字和学号否则会被老师查出来printf(\njungle抄完改名字和学号否则会被老师查出来……\n);jungleWork-setName(jungle);jungleWork-setIdNum(1002);WorkModel *jungleModel new WorkModel();jungleModel-setWorkModelName(Jungle_Model);jungleWork-setModel(jungleModel);// 检查下是否改对了printf(\nSingle的作业\n);singleWork-printWorkInfo();printf(\nJungle的作业\n);jungleWork-printWorkInfo();
// #endif
#if 0
// 下面的代码将不会被编译也不会执行ConcreteWork *singleWork new ConcreteWork(Single, 1001, Single_Model);printf(\nSingle的作业\n);// clone() 返回 PrototypeWork*需类型转换ConcreteWork* jungleWork dynamic_castConcreteWork*(singleWork-clone());printf(\njungle直接抄作业……\n);// 抄完改名字和学号否则会被老师查出来printf(\njungle抄完改名字和学号否则会被老师查出来……\n);jungleWork-setName(jungle);jungleWork-setIdNum(1002);WorkModel *jungleModel new WorkModel();jungleModel-setWorkModelName(Jungle_Model);jungleWork-setModel(jungleModel);// 检查下是否改对了printf(\nSingle的作业\n);singleWork-printWorkInfo();printf(\nJungle的作业\n);jungleWork-printWorkInfo();delete singleWork;delete jungleWork;
#endif return 0;
}显然这不是我们想要的结果。接下来我们使用clone方法。
示例二深拷贝 cpp
#include PrototypePattern.hint main() {
#if 0
// 下面的代码将不会被编译也不会执行ConcreteWork *singleWork new ConcreteWork(Single,1001,Single_Model);printf(\nSingle的作业\n);singleWork-printWorkInfo();printf(\njungle直接抄作业……\n);ConcreteWork *jungleWork singleWork;printf(\nJungle的作业\n);jungleWork-printWorkInfo();// 抄完改名字和学号否则会被老师查出来printf(\njungle抄完改名字和学号否则会被老师查出来……\n);jungleWork-setName(jungle);jungleWork-setIdNum(1002);WorkModel *jungleModel new WorkModel();jungleModel-setWorkModelName(Jungle_Model);jungleWork-setModel(jungleModel);// 检查下是否改对了printf(\nSingle的作业\n);singleWork-printWorkInfo();printf(\nJungle的作业\n);jungleWork-printWorkInfo();
#endif
// #if 0
// 下面的代码将不会被编译也不会执行ConcreteWork *singleWork new ConcreteWork(Single, 1001, Single_Model);printf(\nSingle的作业\n);singleWork-printWorkInfo();// clone() 返回 PrototypeWork*需类型转换printf(\njungle直接抄作业……\n);ConcreteWork* jungleWork dynamic_castConcreteWork*(singleWork-clone());printf(\nJungle的作业\n);jungleWork-printWorkInfo();// 抄完改名字和学号否则会被老师查出来printf(\njungle抄完改名字和学号否则会被老师查出来……\n);jungleWork-setName(jungle);jungleWork-setIdNum(1002);WorkModel *jungleModel new WorkModel();jungleModel-setWorkModelName(Jungle_Model);jungleWork-setModel(jungleModel);// 检查下是否改对了printf(\nSingle的作业\n);singleWork-printWorkInfo();printf(\nJungle的作业\n);jungleWork-printWorkInfo();delete singleWork;delete jungleWork;
// #endif return 0;
}原型模式总结 开闭原则 之后我会持续更新如果喜欢我的文章请记得一键三连哦点赞关注收藏你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 ↖(▔▽▔)↗感谢支持