第三章 装饰者模式

来源:互联网 发布:java人事工资管理系统 编辑:程序博客网 时间:2024/05/22 06:26

装饰者模式

参考《head first 设计模式》
装饰者模式像包了一层层糖纸的糖果,每一层糖纸都继承自同一个基类。遵循开闭设计原则,即对扩展开放,对修改关闭。就是写好的代码能不改就不要改,改了可能要加班加点了。这个模式像那种二道贩子,把别人做好的东西做个包装,添加点自己的东西再拿出去卖。
定义:动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更富有弹性的替代方案。
特征:

  1. 装饰者和被装饰者具有相同的基类;
  2. 可以用一个或多个装饰者包装一个对象;
  3. 既然装饰者和被装饰者具有相同的基类,可以用装饰者替代被装饰者;
  4. 装饰者可以在被装饰者的行为前或后,添加自己的行为;
  5. 对象可以在任何时候被装饰。

心得

装饰者和被装饰者必须要继承自同一个基类的目的是,在装饰者的内部有基类型字段用来保存被装饰者,一个装饰者被再次装饰后,它对于后者而言就成了被装饰者,如果不是继承自同一个基类,它就不能保存到后者的基类型字段里了,从而无法再次被扩展。

## 结构
这里写图片描述

## 示例代码

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 装饰者模式{    class Program    {        static void Main(string[] args)        {            Beverage beverage=new Espresso(); // 一杯浓咖啡,不加调料            Console.WriteLine($"{beverage.GetDescription()} ${beverage.Cost()}");            Beverage beverage2=new DarkRoast(); // 一杯深焙咖啡            beverage2=new Mocha(beverage2); // 添加摩卡            beverage2 = new Mocha(beverage2); // 添加摩卡            beverage2 = new Whip(beverage2); // 添加奶泡            Console.WriteLine($"{beverage2.GetDescription()} ${beverage2.Cost()}");            Beverage beverage3=new HouseBlend(); // 一杯混合咖啡            beverage3=new Soy(beverage3); // 添加豆浆            beverage3=new Mocha(beverage3); // 添加摩卡            beverage3=new Whip(beverage3); // 添加奶泡            Console.WriteLine($"{beverage3.GetDescription()} ${beverage3.Cost()}");            Console.ReadKey();        }    }    #region 计算咖啡饮料的价格   // 咖啡饮料中可能加入不同的饮料,价格也可能会发生改变    // 饮料抽象类,一般装饰者模式用抽象类,也可以用接口    public abstract class Beverage    {       public string Description = "Unknown Beverage";        public virtual string GetDescription()        {            return Description;        }        // 计算饮料价格        public abstract double Cost();    }    // 调料装饰者抽象类,给所有具体的调料类继承    public abstract class CondimentDecorator : Beverage    {        // 覆盖基类中的获取描述的方法        public override string GetDescription()        {            return string.Empty;        }    }    #region 被装饰者组件    // 特浓咖啡类    public class Espresso : Beverage    {        public Espresso()        {            Description = "Espresso";        }        public override double Cost()        {            return 1.99;        }    }    // 混合咖啡类    public class HouseBlend : Beverage    {        public HouseBlend()        {            Description = "HouseBlend";        }        public override double Cost()        {            return 0.89;        }    }    // 深焙咖啡类    public class DarkRoast : Beverage    {        public DarkRoast()        {            Description = "DarkRoast";        }        public override double Cost()        {            return 0.99;        }    }    // 低咖啡因咖啡类    public class Decaf : Beverage    {        public Decaf()        {            Description = "Decaf";        }        public override double Cost()        {            return 1.05;        }    }    #endregion    #region 装饰者    // 各种咖啡配料    // 摩卡    public class Mocha : CondimentDecorator    {        private readonly Beverage _beverage; // 保存被装饰者        public Mocha(Beverage beverage)        {            _beverage = beverage;        }        public override string GetDescription()        {            return _beverage.GetDescription() + ", Mocha";        }        public override double Cost()        {            return .20 + _beverage.Cost();        }    }    // 牛奶    public class Milk : CondimentDecorator    {        private readonly Beverage _beverage; // 保存被装饰者        public Milk(Beverage beverage)        {            _beverage = beverage;        }        public override string GetDescription()        {            return _beverage.GetDescription() + ", Milk";        }        public override double Cost()        {            return .10 + _beverage.Cost();        }    }    // 豆浆    public class Soy : CondimentDecorator    {        private readonly Beverage _beverage; // 保存被装饰者        public Soy(Beverage beverage)        {            _beverage = beverage;        }        public override string GetDescription()        {            return _beverage.GetDescription() + ", Soy";        }        public override double Cost()        {            return .15 + _beverage.Cost();        }    }    // 奶泡    public class Whip : CondimentDecorator    {        private readonly Beverage _beverage; // 保存被装饰者        public Whip(Beverage beverage)        {            _beverage = beverage;        }        public override string GetDescription()        {            return _beverage.GetDescription() + ", Whip";        }        public override double Cost()        {            return .10 + _beverage.Cost();        }    }    #endregion    #endregion}
原创粉丝点击