1. 程式人生 > >通過例子學設計模式之--原型模式以及使用場景說明(C++實現)

通過例子學設計模式之--原型模式以及使用場景說明(C++實現)

           想必很多人都玩過魔獸爭霸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;
}