简介
UMl
特点
可以在程序运行时(对象属性发生了变化),得到一份内容相同的实例,但之间还不会相互干扰。
缺陷
使用场景跟拷贝构造相似度很高,能用拷贝构造(注意考虑深浅拷贝)解决不用非得搞设计模式。
注意
但是使用了原型模式就是不想暴露给用户对象创建过程。只能通过clone来获取对象的拷贝。和工厂模式可以搭配,隐藏对象的创建细节。
代码
#include <string>
#include <iostream>
using namespace std;
class A
{
public:
void fun(){}
string number;
};
// 抽象产品接口,包含克隆模式的 clone 接口,与要实现的功能接口
class AbstractProduct{
public:
virtual AbstractProduct* clone() = 0;
virtual void myPrototype() const = 0;
};
// 具体产品
class ConcreteProduct : public AbstractProduct,A
// class ConcreteProduct : public A, AbstractProduct // 继承顺序改变会导致编译时类的函数排版发生变化
{
public:
explicit ConcreteProduct(const string & name){ this->name = name;}
ConcreteProduct(ConcreteProduct &src){/**< 拷贝构造什么也不干 */}
void myPrototype() const override {cout << name << endl;}
AbstractProduct* clone(){
return new ConcreteProduct(this->name);
}
string name;
};
// 简单工厂
class Factor
{
public:
enum ProductType{
COMMON
};
AbstractProduct* create(ProductType type, const string & name){
if (COMMON == type)
return new ConcreteProduct(name);
}
};
#define TO_STR(str) #str
int main()
{
A a;
a.number = "xiaoming";
A a1 = a;
cout<< "a1.number : " << a1.number << endl;
cout<< "*************************************" << endl;
Factor factor;
AbstractProduct* concreteProduct1 = factor.create(Factor::COMMON,TO_STR(concreteProduct1));
concreteProduct1->myPrototype();
cout<< "*************************************" << endl;
AbstractProduct* concreteProduct2 = concreteProduct1->clone();
concreteProduct2->myPrototype();
cout<< "*************************************" << endl;
// 暴力采用等号的方式复制对象。要是拷贝构造不能完全复制对象或者没有实现深拷贝。会导致问题
ConcreteProduct concreteProduct3 = *static_cast<ConcreteProduct*>(concreteProduct1);
// 使用此方式耍小聪明偷鸡,只能特殊情况下成功。详见22行代码。
concreteProduct3.myPrototype();
cout<< "*************************************" << endl;
}
输出:
a1.number : xiaoming
*************************************
concreteProduct1
*************************************
concreteProduct1
*************************************
*************************************
使用场景
1.不想暴露拷贝过程。或过程复杂代码重复量高
2.对象使用的是工厂模式创建的,只能拿到父类指针,使用 *指针 取不到子类对象的值。