想必很多人都玩过魔兽争霸3。里面有一个非常厉害的英雄叫做剑圣。这个英雄攻击力算是最高的,而且有个听起来很叼的魔法,“剑刃风暴”,这个魔法其实效果一般,不大实用。
剑圣有一个分身的功能。这个分身各个方面和剑圣都一模一样,但是没有攻击力,也没有魔法。
1 这个分身是游戏过程中动态生成的。剑圣使用了这个功能就动态生成分身。
2 这个分身几乎就是剑圣的拷贝。如果重新new一个剑圣不符合游戏规则。玩过War3的人都知道一个种族只能有一个剑圣吧,如果可以有3个剑圣,让其它族怎么玩。
3 重新创建一个剑圣很麻烦,要初始化各种参数,如等级啊,攻击力啊,等等各个参数,而且这些参数要和原型一致。直接通过原型模式实现则简单。
剑圣有一个分身的功能。这个分身各个方面和剑圣都一模一样,但是没有攻击力,也没有魔法。
如何实现这个分身的功能呢?使用原型模式。原型模式就是这么一个道理,通过现有的东西,用Clone再复制拷贝出一个或者多个。
1 这个分身是游戏过程中动态生成的。剑圣使用了这个功能就动态生成分身。
2 这个分身几乎就是剑圣的拷贝。如果重新new一个剑圣不符合游戏规则。玩过War3的人都知道一个种族只能有一个剑圣吧,如果可以有3个剑圣,让其它族怎么玩。
3 重新创建一个剑圣很麻烦,要初始化各种参数,如等级啊,攻击力啊,等等各个参数,而且这些参数要和原型一致。直接通过原型模式实现则简单。
4 便于扩展。如果分身有30%原剑圣的攻击力,那么我们直接修改Clone方法即可。对外的接口不用变更。
下面是实现代码:
//相当于类图中的Prototype,也就是原型
class Hero
{
public:
Hero(int damage,string magic)//构造函数
{
SetDamage(damage);
SetMagic(magic);
}
Hero(const Hero & h) //拷贝构造函数
{
SetDamage(h.m_damage);
SetMagic(h.m_magic);
}
void SetDamage(int damage)
{
m_damage = damage;
}
void SetMagic(string magic)
{
m_magic = magic;
}
void Attach() //攻击
{
printf("Hero Attach damage: %d\r\nHero magic: %s\r\n",m_damage,m_magic.c_str());
}
virtual ~Hero(){}
virtual Hero* Clone() = 0;
protected:
int m_damage;//攻击力
string m_magic;//魔法
};
//相当于类图中的ConcretePrototype
class BM : public Hero //BM 剑圣
{
public:
BM(int damage,string magic) : Hero(damage,magic){}
~BM(){}
BM(const BM& bm) : Hero(bm) //拷贝构造函数
{
}
Hero* Clone()
{
BM* bm = new BM(*this);
bm->SetDamage(0);
bm->SetMagic("No Magic");
return bm;
}
};
//相当于类图中的Client
//场景测试
void TestProtoType()
{
Hero* bm = new BM(98,"剑刃风暴");
bm->Attach();
Hero* bm1 = bm->Clone();
bm1->Attach();
delete bm;
delete bm1;
}