首页 > 代码库 > 装饰者模式

装饰者模式

四人组之装饰者模式。

1、例子:饮料和调料包之间的计价功能等实现。

2.实质上:相同接口,实现功能的不断扩充。

3.优美的一句话:“代码应如晚霞中池中莲花一样关闭(免于改变),又如晨曦中此花一样绽放(功能扩展)”。不修改代码的情况下进行扩展

4.实质上:装饰者可以在被装饰者行为之前(后)加上自己的行为,

为什么装饰者和被装饰者继承同一个baseclass ?

为了和被装饰者在类型匹配的基础上达到新的行为

技术分享

实现:

  1    static void Main(string[] args)
  2     {
  3         Coffee myCoffee = new Coffee(10);//一个被装饰者对象
  4 
  5         DecoratorBase myDecorate = new DecoratorSugar(myCoffee, 0.1);//创建装饰者
  6         myDecorate = new DecoratorSugar(myDecorate, 0.1);//双糖
  7         myDecorate = new DecoratorMilk(myDecorate, 0.3);
  8 
  9         Console.WriteLine("price:" + myDecorate.GetCost());
 10         Console.WriteLine("describe:" + myDecorate.GetDescribe());
 11     }
 12 
 13     /// <summary>
 14     /// 饮料相关基类:装饰者和被装饰者
 15     /// </summary>
 16     class Drink
 17     {
 18         protected string mDescribe = string.Empty;
 19         protected double mCost = 0.0;
 20 
 21         public Drink()
 22         {
 23             mDescribe = "--BaseDrink--";
 24         }
 25 
 26         public virtual string GetDescribe()
 27         {
 28             return mDescribe;
 29         }
 30         public virtual double GetCost()
 31         {
 32             return mCost;
 33         }
 34     }
 35 
 36     /// <summary>
 37     /// 被装饰者:咖啡
 38     /// </summary>
 39     class Coffee : Drink
 40     {
 41         public Coffee(double price)
 42         {
 43             mDescribe = "--Coffee--";
 44             mCost = price;
 45         }
 46     }
 47     /// <summary>
 48     /// 被装饰者:果汁
 49     /// </summary>
 50     class Juice : Drink
 51     {
 52         public Juice(double price)
 53         {
 54             mCost = price;
 55         }
 56     }
 57 
 58     /// <summary>
 59     /// 装饰者
 60     /// </summary>
 61     class DecoratorBase : Drink
 62     {
 63         protected Drink mDrink = null;
 64 
 65         public DecoratorBase(Drink drink, double price)
 66         {
 67             mDrink = drink;
 68 
 69             mCost = price;
 70             mDescribe = "--decorate--";
 71         }
 72     }
 73 
 74     class DecoratorSugar : DecoratorBase
 75     {
 76         public DecoratorSugar(Drink drink, double price)
 77             : base(drink, price)
 78         {
 79             mDescribe = "--sugar--";
 80         }
 81 
 82         public override string GetDescribe()
 83         {
 84             return mDescribe + mDrink.GetDescribe();
 85         }
 86 
 87         public override double GetCost()
 88         {
 89             return mCost + mDrink.GetCost();
 90         }
 91 
 92     }
 93 
 94     class DecoratorMilk : DecoratorBase
 95     {
 96         public DecoratorMilk(Drink drink, double price)
 97             : base(drink, price)
 98         {
 99             mDescribe = "--Milk--";
100         }
101         public override string GetDescribe()
102         {
103             return mDescribe + mDrink.GetDescribe();
104         }
105 
106         public override double GetCost()
107         {
108             return mCost + mDrink.GetCost();
109         }
110     }

 

结果:

技术分享

 

 

添加功能:我们需要给每个饮料设置 小、中、大杯和不同价格,对应的调料包的需要小中大和不同价格。

调料的大中小不是自己决定的,而是由饮料决定的。

 

技术分享
  1    static void Main(string[] args)
  2     {
  3         Coffee myCoffee = new Coffee(10, SizeType.Min);//一个被装饰者对象
  4 
  5         DecoratorBase myDecorate = new DecoratorSugar(myCoffee, 0.1);//创建装饰者
  6         myDecorate = new DecoratorSugar(myDecorate, 0.1);//双糖
  7         myDecorate = new DecoratorMilk(myDecorate, 0.3);
  8 
  9         Console.WriteLine("price:" + myDecorate.GetCost());
 10         Console.WriteLine("describe:" + myDecorate.GetDescribe());
 11     }
 12 
 13     enum SizeType
 14     {
 15         Max = 1,
 16         Mid = 2,
 17         Min = 3,
 18     }
 19 
 20     public static double[] percentPrice = { 1, 0.8, 0.5 };//每个调料包size价格百分比
 21 
 22     /// <summary>
 23     /// 饮料相关基类:装饰者和被装饰者
 24     /// </summary>
 25     class Drink
 26     {
 27         protected string mDescribe = string.Empty;
 28         protected double mCost = 0.0;
 29         protected SizeType mSizeType = SizeType.Max;
 30 
 31         public Drink()
 32         {
 33             mDescribe = "--BaseDrink--";
 34         }
 35 
 36         public virtual string GetDescribe()
 37         {
 38             return mDescribe;
 39         }
 40         public virtual double GetCost()
 41         {
 42             return mCost;
 43         }
 44 
 45         public SizeType GetSize()
 46         {
 47             return mSizeType;
 48         }
 49     }
 50 
 51     /// <summary>
 52     /// 被装饰者:咖啡
 53     /// </summary>
 54     class Coffee : Drink
 55     {
 56         public Coffee(double price, SizeType sizeType)
 57         {
 58             mDescribe = "--Coffee--";
 59             mCost = price;
 60             mSizeType = sizeType;
 61         }
 62     }
 63     /// <summary>
 64     /// 被装饰者:果汁
 65     /// </summary>
 66     class Juice : Drink
 67     {
 68         public Juice(double price, SizeType sizeType)
 69         {
 70             mDescribe = "--Juice--";
 71             mCost = price;
 72             mSizeType = sizeType;
 73         }
 74     }
 75 
 76     /// <summary>
 77     /// 装饰者
 78     /// </summary>
 79     class DecoratorBase : Drink
 80     {
 81         protected Drink mDrink = null;
 82 
 83         public DecoratorBase(Drink drink, double price)
 84         {
 85             if (drink != null)
 86             {
 87                 mDrink = drink;
 88 
 89                 mCost = price;
 90                 mDescribe = "--decorate--";
 91 
 92                 mSizeType = mDrink.GetSize();
 93             }
 94         }
 95     }
 96 
 97     class DecoratorSugar : DecoratorBase
 98     {
 99         public DecoratorSugar(Drink drink, double price)
100             : base(drink, price)
101         {
102             mDescribe = "--sugar--";
103         }
104 
105         public override string GetDescribe()
106         {
107             return mDescribe + mDrink.GetDescribe();
108         }
109 
110         public override double GetCost()
111         {
112             double percent = percentPrice[(int)mSizeType - 1];
113             return mCost * percent + mDrink.GetCost();
114         }
115 
116     }
117 
118     class DecoratorMilk : DecoratorBase
119     {
120         public DecoratorMilk(Drink drink, double price)
121             : base(drink, price)
122         {
123             mDescribe = "--Milk--";
124         }
125         public override string GetDescribe()
126         {
127             return mDescribe + mDrink.GetDescribe();
128         }
129 
130         public override double GetCost()
131         {
132             double percent = percentPrice[(int)mSizeType - 1];
133             return mCost * percent + mDrink.GetCost();
134         }
135     }
View Code

 

装饰者模式