设计模式:装饰器模式
装饰器模式:就是对已经存在的某些类进行装饰,以此来扩展一些功能。
下面通过现实生活中的一个示例来阐述一下装饰器模式:
//煎饼的抽象 public abstract class AbstractPancake { /// <summary> /// 煎饼 /// </summary> public abstract string CreatePancake(); /// <summary> /// 价格 /// </summary> public abstract int Cost(); } // 煎饼的具体类 public class Pancake : AbstractPancake { public override int Cost() { return 5; } public override string CreatePancake() { return "山东大煎饼"; } } ///////////配菜(具体的装饰) /// <summary> /// 加鸡蛋 /// </summary> public class AddEgg : AbstractPancake { private AbstractPancake _Pancake = null; public AddEgg(AbstractPancake pancake) { this._Pancake = pancake; } public override int Cost() { return (int)this._Pancake.Cost() + 2; } public override string CreatePancake() { return this._Pancake.CreatePancake() + " 加鸡蛋"; } } /// <summary> /// 加火腿肠 /// </summary> public class AddSausage : AbstractPancake { private AbstractPancake _Pancake = null; public AddSausage(AbstractPancake pancake) { this._Pancake = pancake; } public override int Cost() { return (int)this._Pancake.Cost() + 3; } public override string CreatePancake() { return this._Pancake.CreatePancake() + " 加火腿肠"; } } //顾客 public class Customer { public string Name { get; set; } public Customer(string name) { Name = name; } public void Buy(AbstractPancake pancake) { Console.WriteLine($"{Name} 购买了:{pancake.CreatePancake()} 一份,花费:{pancake.Cost()} 元!"); } } internal class Program { static void Main(string[] args) { //张三,要一个原味的煎饼 Customer customer1 = new Customer("张三"); AbstractPancake pancake = new Pancake(); customer1.Buy(pancake); Console.WriteLine("***********************"); //加鸡蛋 加火腿肠 Customer customer2 = new Customer("谭勇君"); AbstractPancake pancake1 = new Pancake(); pancake1 = new AddEgg(pancake1); pancake1 = new AddSausage(pancake1); customer2.Buy(pancake1); Console.ReadKey(); } }
上面的代码以煎饼为主体,用配菜来“装饰”煎饼,然后根据每个顾客的需求进行装饰煎饼。
通过上面的示例可以发现装饰器模式有以下优点:
1.装饰类和被装饰类可以独立发展,而不会相互耦合。例如:AbstractPancake类无须知道装饰类(AddEgg、AddSausage),装饰类是从外部来扩展AbstractPancake类的功能,而装饰类也不用知道具体的细节。
2.装饰模式是继承关系的一个替代方案,装饰类不管装饰多少层,他始终是一个抽象类实现的,所以他是继承的一种良好替代方案。
装饰器模式虽然从数量级上减少了类的数量,但是为了要装饰,仍旧会增加很多的小类,这些具体的装饰类的逻辑将不会非常的清晰,不够直观,容易令人迷惑。还就是装饰器模式虽然减少了类的爆炸,但是在使用的时候,你就可能需要更多的对象来表示继承关系中的一个对象,多层的装饰是比较复杂,比如查找问题时,被层层嵌套,不容易发现问题所在。