類應該對擴展開放,對修改封閉。
(本故事純屬虛構)
某日早上,流年剛把新開發的游戲項目提交給經理
1 public abstract class Role 2 { 3 public virtual string RoleName { get; private set; } 4 public abstract int PhysicalAttack(); 5 }
1 class Samurai : Role 2 { 3 public override string RoleName 4 { 5 get 6 { 7 return "武士"; 8 } 9 } 10 public override int PhysicalAttack() 11 { 12 return 999; 13 } 14 }
(當然這還算不上個游戲),項目經理看了沒幾分鐘,“這什麼屌逼玩意?游戲角色都不帶裝備的!!! 玩家還玩個屁啊”;
“那好吧,給角色加把武器?”我弱弱的回了句。
“你個2屌,加個武器就夠了?至少弄上個法寶、寶寶、套裝....”。經理逼逼了一大堆。
"我靠,那怎麼改?"我在心裡默念了一句。
“回去好好改去,******”經理又逼逼了一大堆。
流年一溜煙,跑出了經理辦公室,“還好溜的快,要不然口水都夠洗臉了”。
趕緊回去把代碼改了下,*****,樓主指尖在鍵盤上框框飛舞。
突然想到,我靠,要是哪天經理又要加點什麼東西,豈不是很麻煩。
趕緊Google找了本小黃書看了下,看看有什麼好方法。哈哈哈...,有了,就是它了——《裝飾者模式》。
於是。。。
1 //把裝飾者抽象一下,這樣再加什麼東西直接繼承他就行 2 public abstract class PropDocorator : Role 3 { 4 Role _role; 5 public PropDocorator(Role role) 6 { 7 _role = role; 8 } 9 public override string RoleName 10 { 11 get { return this._role.RoleName; } 12 } 13 public abstract string Docorate(); 14 //新加了元素攻擊 15 public abstract int ElementAttack(); 16 }
通過組合的方式,擴展了角色原有的功能,而且不需要去動原來的代碼。
給你加把刀試試火力
1 class Knife:PropDocorator 2 { 3 Role _role; 4 private string _name = "貪狼刀"; 5 6 public Knife(Role role):base(role) { 7 _role = role; 8 } 9 10 public override string Docorate() 11 { 12 return this._role.RoleName + "裝配" + this._name; 13 } 14 15 public override int PhysicalAttack() 16 { 17 return this._role.PhysicalAttack() + 1000; 18 } 19 20 public override int ElementAttack() 21 { 22 return 1200; 23 } 24 }
好了,該加的都加上了,趕緊Debug下,試試
O了,這下再加個裝備就簡單了,直接繼承裝飾者的基類,去實現就行。趕緊把項目Submit,流年大搖大擺走進了經理辦公室...
裝飾者模式動態的將職責附加到對象上。若要擴展功能,裝飾著可以比繼承提供更具有彈性的方案。
使代碼具有彈性,可以應對改變,可以接受新的功能來應對改變的需求。