装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

举例:咖啡厅想要升级点餐系统,假设咖啡厅有美国咖啡与中国咖啡两种,价格不同,客人可以选择在咖啡中加入调料如牛奶或者橙子或者还有很多其他的调料,牛奶和橙子对应不同的价格,结账金额=咖啡的价格+调料的价格;咖啡有:大杯、普通杯、小杯,如果加调料豆子,分别对应收取的价格2,1.5,1

实现代码如下:

 /// <summary>
    /// 抽象“饮料”  被修饰者
    /// </summary>
    public abstract class Beverage
    {

        protected Beverage beverage;
        public abstract string GetDescription();
        public abstract double Cost();
        BeverageSize size;
        public void SetSize(BeverageSize _size)
        {
            size = _size;
        }
        protected BeverageSize GetSize()
        {
            return size;
        }
    }

    public enum BeverageSize
    {
        big,
        normal,
        small
    }

  实现类:

public class ChineseCoffee:Beverage
    {

        public override double Cost()
        {
            return 2;
        }


        public override string GetDescription()
        {
            return "中国咖啡"; ;
        }
    }


  public class AmericanCoffee:Beverage
    {
        public override double Cost()
        {
            return 1.0;
        }

        public override string GetDescription()
        {
            return "美国咖啡," + GetSize()+"杯";
        }
    }

  装饰类:

 public class DecorateMilk : Beverage
    {

       public DecorateMilk(Beverage _Beverage)
       {
           beverage = _Beverage;

       }
        public override double Cost()
        {
            return beverage.Cost() + 0.5;
        }

        public override string GetDescription()
        {
            return beverage.GetDescription() + ",Milk";
        }


    }


 public class DecorateOrange : Beverage
    {

       public DecorateOrange(Beverage _Beverage)
       {
           beverage = _Beverage;

       }
        public override string GetDescription()
        {
            return beverage.GetDescription() + ",Orange";
        }

        public override double Cost()
        {
            return beverage.Cost() + 0.6;
        }
    }


public class Soy:Beverage
{

public Soy(Beverage b)
{
beverage = b;
}
public override string GetDescription()
{
return beverage.GetDescription() + ",Soy";
}

public override double Cost()
{
if (GetSize() == BeverageSize.big)
{
return beverage.Cost() + 2;
}
else if (GetSize() == BeverageSize.normal)
{
return beverage.Cost() + 1.5;
}
else
{
return beverage.Cost() + 1;
}
}
}

  测试一下:

  class Program
    {
        static void Main(string[] args)
        {
            Beverage b = new AmericanCoffee();
            b = new DecorateMilk(b);
            b = new DecorateOrange(b);
            b = new Soy(b);
            b.SetSize(BeverageSize.big);
            Console.Write(b.GetDescription()+","+b.Cost());
            Console.ReadKey();
        }
    }

  结果:美国咖啡,big杯,Milk,Orange,Soy,4.1

01-31 19:35