C++实现原型模式

拷贝构造和原型模式有什么区别?

文章目录

      • 1. 情景与意图
      • 2. 原型模式
      • 3. 克隆动物
      • 4. 总结

1. 情景与意图

  在我们日常写代码的时候,有一段代码两三百行,在网络上的某处。我们是应该敲出来呢?还是Ctrl C + Ctrl V呢?肯定是第二个啊。这个例子不太好。再比如,某员工每天需要给三个领导一份纸质的日报,员工不会每次都手打三份,而是写一份,然后直接打印三份。这个打印的操作就是稳定的,每天不同的日报就是变化的。
  在日常开发中,会面临着复杂对象的创建工作,该对象确经常发生变化,但是却有一致稳定的接口。我们能否提供一个方法让我们依赖这个稳定的接口,从而隔离变化的对象呢?——原型模式。

2. 原型模式

  用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
  这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。类似于拷贝构造的操作。
  当学习这个模式的时候,心里肯定会有一个疑问,就是这个和拷贝构造有什么区别?这个在后面进行解释。

3. 克隆动物

我们先通过代码,来认识一下原型模式。
我们有一个抽象的动物类。

class DPAbstractClonedAnimal {
protected:
	std::string _name;
public:
	virtual void AnimalCry() = 0;
	// 可以纯虚也可以不纯虚
	virtual DPAbstractClonedAnimal* clone() = 0;
};

来实现几个具体的动物:

class DPClonedSheep : public DPAbstractClonedAnimal {

public:
	DPClonedSheep(std::string name);
	// 对于原型模式,我们需要对拷贝构造函数严格的实现,因为原型模式,其实就是调用的拷贝构造
	DPClonedSheep(const DPClonedSheep& sheep);
	virtual void AnimalCry();
	virtual DPAbstractClonedAnimal* clone();
};

class DPClonedCattle : public DPAbstractClonedAnimal {

public:
	DPClonedCattle(std::string name);
	DPClonedCattle(const DPClonedCattle& cattle);
	virtual void AnimalCry();
	virtual DPAbstractClonedAnimal* clone();
};

实现克隆羊,克隆牛其实同理:

DPClonedSheep::DPClonedSheep(std::string name) {
	_name = name;
}
DPClonedSheep::DPClonedSheep(const DPClonedSheep& sheep) {
   // 拷贝构造简单实现
	_name = std::string("克隆羊") + sheep._name;
}
void DPClonedSheep::AnimalCry() {
	std::cout << _name << "咩咩咩" << std::endl;
}
DPAbstractClonedAnimal* DPClonedSheep::clone() {
	// 其实调用的还是拷贝构造
	return new DPClonedSheep(*this);
}

使用一下:

int main() {
	// 对于动物类,我们应该用工厂模式创建对象,不依赖具体的类
	DPAbstractClonedAnimal* sheepOne = new DPClonedSheep("喜羊羊");
	sheepOne->AnimalCry();
	DPAbstractClonedAnimal* sheepTwo = sheepOne->clone();
	sheepTwo->AnimalCry();
	DPAbstractClonedAnimal* cattleOne = new DPClonedCattle("大角牛");
	cattleOne->AnimalCry();
	DPAbstractClonedAnimal* cattleTwo = cattleOne->clone();
	cattleTwo->AnimalCry();
	return 0;
}

4. 总结

拷贝构造和原型模式有什么区别?
  设计模式一直在强调的事情就是依赖抽象,控制变化。如果我们在这里直接使用拷贝构造,那么一定是需要使用一个具体的类,使用具体得类就产生了依赖,在面对变化的对象的时候就不能满足。
  如果说我们一个对象的创建非常的复杂,而对象有经常发生变化,这个时候可以使用原型模式。
原型模式源代码:【原型模式代码C++源码】

你可能感兴趣的:(#,设计模式系列,c++,设计模式)