装饰者模式(Decorator pattern)
知识点
类应该对扩展开放,对修改封闭。
案例
(本故事纯属虚构)
某日早上,流年刚把新开发的游戏项目提交给经理
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,流年大摇大摆走进了经理办公室...
小结
装饰者模式动态的将职责附加到对象上。若要扩展功能,装饰着可以比继承提供更具有弹性的方案。
使代码具有弹性,可以应对改变,可以接受新的功能来应对改变的需求。