通過例子學設計模式之--原型模式以及使用場景說明(C++實現)
阿新 • • 發佈:2019-01-08
想必很多人都玩過魔獸爭霸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; }