原型模式是一种创建型设计模式,使用它可以复制已有对象,并且不需要依赖已有对象所属的类。
如果需要复制一个对象,该怎么做呢?
称想要复制的对象为对象A,复制得到的对象为对象B。分为两步:
- 用A的类新建一个实例对象,这个对象就是B
- 把A的所有属性值都赋值给B。复制结束。
这两步每一步都有问题,第一步当前代码必须能够访问A所属的类,有一种场景,方法的参数是接口类型,一个类只要实现了接口,其对象就可以作为参数传递。这时方法里的代码无法访问参数的实际类型。
第二步,A所属的类有些属性是私有的。从外部无法访问。
解决办法:原型模式
原型模式将上门的两步从A类外转移到A类内,那么上面两步的问题就不存在了。声明一个包含克隆方法的通用接口interface,让A的类实现这个接口。当需要A的克隆对象时,只需要A调用克隆方法即可。
类图:
代码示例:
#include <iostream>
#include <string>
// 1. 原型接口
class Prototype {
public:
virtual Prototype* clone() const = 0;
virtual void display() const = 0;
};
// 2. 具体原型
class ConcretePrototype : public Prototype {
public:
ConcretePrototype(int field1)
: field1_(field1) {}
// 实现深拷贝
Prototype* clone() const override {
return new ConcretePrototype(*this);
}
void display() const override {
std::cout << "ConcretePrototype: Field1 = " << field1_ << std::endl;
}
int getField1() const {
return field1_;
}
private:
int field1_;
};
// 3. 具体原型的子类
class SubConcretePrototype : public ConcretePrototype {
public:
SubConcretePrototype(int field1, std::string field2)
: ConcretePrototype(field1), field2_(std::move(field2)) {}
// 实现深拷贝
Prototype* clone() const override {
return new SubConcretePrototype(*this);
}
void display() const override {
std::cout << "SubConcretePrototype: Field1 = " << getField1() << ", Field2 = " << field2_ << std::endl;
}
std::string getField2() const {
return field2_;
}
private:
std::string field2_;
};
int main() {
// 使用原型模式创建新对象
ConcretePrototype prototype(42);
prototype.display();
// 克隆原型对象
Prototype* clonedPrototype = prototype.clone();
clonedPrototype->display();
// 使用具体原型的子类创建新对象
SubConcretePrototype subPrototype(1, "Hello");
subPrototype.display();
// 克隆具体原型的子类对象
Prototype* clonedSubPrototype = subPrototype.clone();
clonedSubPrototype->display();
// 释放资源
delete clonedPrototype;
delete clonedSubPrototype;
return 0;
}