一.介绍
装饰者模式(Decorator Pattern)。属于结构型模式。动态地给一个对象添加额外的职责,就增加功能来说,装饰者模式比添加子类更为灵活。
二.实现
举个例子,定义一个类是一个人,那这个人能够打拳,一拳出来就可以造成物理伤害。后来这个人得到了一套外挂,用了外挂后,一拳出来不光可以造成物理伤害,还能造成火属性伤害。这种情况就适合使用装饰者模式,给这个人添加了额外的功能(造成火属性伤害),但又不改变这个人的基本属性(只能造成物理伤害)。
/// <summary> /// 人 装饰者模式中的抽象构件 /// </summary> public interface IPeople { public void Beat(); } /// <summary> /// 主角 装饰者模式中的具体构件 /// </summary> public class Man : IPeople { public void Beat() { Console.WriteLine("一拳造成物理伤害"); } } /// <summary> /// 外挂 装饰者模式中的装饰,要让装饰完全取代抽象组件,必须继承 /// 通俗的说,这件外挂一定是要给人用,总不能让条鱼打拳吧 /// </summary> public class Cheater : IPeople { private readonly IPeople _people; protected Cheater(IPeople people) { _people = people; } public virtual void Beat() { if (_people != null) { _people.Beat(); } } } /// <summary> /// 火属性外挂 装饰者模式中具体装饰者 /// </summary> public class FireCheater : Cheater { public FireCheater(IPeople people) : base(people) { } public override void Beat() { base.Beat(); //新的操作 Console.WriteLine("一拳造成火属性伤害"); } } /// <summary> /// 冰属性外挂 装饰者模式中具体装饰者 /// </summary> public class IceCheater : Cheater { public IceCheater(IPeople people) : base(people) { } public override void Beat() { base.Beat(); //新的操作 Console.WriteLine("一拳造成冰属性伤害"); } } //调用 public static void Main(string[] args) { //主角 IPeople man = new Man(); //开火属性外挂 Cheater fireCheater = new FireCheater(man); //一拳(火) fireCheater.Beat(); Console.WriteLine("---------------------- "); //开冰属性外挂 Cheater iceCheater = new IceCheater(man); //一拳(冰) iceCheater.Beat(); Console.WriteLine("---------------------- "); //同时开火属性和冰属性外挂 //先开火属性外挂 Cheater newFireCheater = new FireCheater(man); //再开冰属性外挂 Cheater newIceCheater = new IceCheater(newFireCheater); //一拳(火、冰) newIceCheater.Beat(); }
从上面可以看出,主角可以动态开挂,需要打什么伤害就去开什么挂,以后也可以另外获得新的外挂,也不会改变主角的基础属性(吃了恶魔果实,会变成旱鸭子,这就不是装饰者模式弄的)。
三.总结
优点:
1.装饰者模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活 。
2.通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合。
3.装饰者模式有很好地可扩展性。
缺点:
1.装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。
参考:https://www.cnblogs.com/guyun/p/6186183.html