原型模式

一 摘要

本章主要说明原型模式,该设计模式主要意图是:用原型实例指定创建对象,并且通过拷贝这些原型创建新的对象。 简单地说就是克隆一个和自己相同的对象。
 
举一个最简单的例子来说明原型模式:英雄联盟有个英雄叫做小丑,小丑可以放置分身,但是这个肯定不能创建,要不就有两个小丑了,这时我们可以从本身克隆出一个。

为什么要使用原型模式?

原型模式和建造者模式、工厂方法模式一样,都属于创建型模式的一种。简单的来说,我们使用原型模式,就是为了创建对象。但是,在以下场景下,使用原型模式是最好的选择:

当我们的对象类型不是开始就能确定的,而这个类型是在运行期确定的话,那么我们通过这个类型的对象克隆出一个新的对象比较容易一些;有的时候,我们需要一个对象在某个状态下的副本,此时,我们使用原型模式是最好的选择;例如:一个对象,经过一段处理之后,其内部的状态发生了变化;这个时候,我们需要一个这个状态的副本,如果直接new一个新的对象的话,但是它的状态是不对的,此时,可以使用原型模式,将原来的对象拷贝一个出来,这个对象就和之前的对象是完全一致的了;当我们处理一些比较简单的对象时,并且对象之间的区别很小,可能就几个属性不同而已,那么就可以使用原型模式来完成,省去了创建对象时的麻烦了;

二. UML类图

在这里插入图片描述
主要参与者
该设计模式的参与者有三个,分别是:

  1. Prototype 抽象原型,克隆自生的抽象接口;
  2. ConcretePrototype 具体原型实现,实现克隆自生各个部件的具体实现接口;
  3. Client 用户,让一个原型克隆自生从而创建一个新的对象;

三 例子

//相当于类图中的Prototype,也就是原型
class Hero
{
public:
	Hero() {};
	Hero(int * attack, int * blood) :m_pAttack(attack), m_pBlood(blood) {}
	Hero(const Hero & hero)//重写拷贝构造
	{
		m_pAttack = new int(*hero.m_pAttack);
		m_pBlood = new int(*hero.m_pBlood);
	}
	void show()
	{
		cout << "攻击力:" << *m_pAttack << "\t血量:" << *m_pBlood << endl;
	}
	virtual Hero* Clone() = 0;

	~Hero()
	{
		if (m_pAttack)
		{
			delete m_pAttack;
			m_pAttack = NULL;
		}
		if (m_pBlood)
		{
			delete m_pBlood;
			m_pBlood = NULL;
		}
	}
protected:
	int* m_pAttack = NULL;//用指针主要是上面拷贝构造-深拷贝
	int* m_pBlood = NULL;

};


//相当于类图中的ConcretePrototype
class Joker :public Hero
{
public:
	Joker(int *attack, int* blood) :Hero(attack, blood) {}
	Joker(const Joker &joker) :Hero(joker) {}//调用父类拷贝构造
	Hero* Clone()
	{
		Joker* joker = new Joker(*this);
		//调用拷贝构造后,可以自己对属性设置
		*joker->m_pAttack = (*m_pAttack/2);
		*joker->m_pBlood = (*m_pBlood /2);
		return joker;
	}
};

//相当于类图中的Client
int main()
{	
	Hero *joker = new Joker(new int(100), new int(100));
	Hero *fake = joker->Clone();

	joker->show();
	fake->show();
		
	delete joker;
	delete fake;

	getchar();
	return 0;
}

浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用 深拷贝:
创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

四 优缺点

优点

  1. 方便在运行时刻增加和删除产品;
  2. 改变值以指定新的对象;
  3. 改变结构以指定新的对象;
  4. 减少子类的构造;
  5. 用类动态配置应用;

五 总结

依我的目前理解,其实就是一个特殊的拷贝构造

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值