装饰者模式

1 首先还是介绍装饰者模式的定义

  装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方式。

  设计原则: 开放关闭。类对扩展开放,对修改关闭。

  利用继承设计子类的行为,是在编译时静态决定的,而且所有子类都会继承相同的行为,然而,如果能够利用组合的方式扩展对象的行为,就可以动态的进行扩展。这样,

可以在后期尽可能少的避免修改代码而是加入新的代码。也就减少引入bugDE 副作用。

2 认识装饰者模式

  可以把装饰者模式理解成一种包装,包装完的对象还是这个对象,只不过赋予了他一种新的形象。就像我们带了个帽子 ,自己还是自己。帽子只是装饰。这是一个不断地嵌套的过程。

每次都用最后装饰完的形象代表自己。

  通过调用最外圈的装饰者就可以调用人最终的行为和属性。

  好了,这是目前我们所知道的一切.......

  1.装饰者和被装饰者对象必须有相同的超类型。

  2.你可以用一个或多个装饰者包装一个对象。

  3.既然装饰者和被装饰者有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它。

  4.装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。

  5.对象可以在任何时候被装饰,所以可以在运行时动态地,不限量地用你喜欢的装饰者来装饰对象。

3类图:

4 举例 ,给咖啡加点料

1  建立 被装饰者的饮料类 

    public abstract class Beverage
    {
      public  string description = "unknow beberage";
        public string getDescription()
        {
            return description;
        }
        public abstract double cost();
    }

2 装饰者类 

   public abstract class condimentDecorator:Beverage  // 必须让装饰者能取代被装饰者,所以他们必须扩展自同一个类
    {
        public abstract string getDescription();
    }

3具体的被装饰者   具体的饮料

 public class espresso:Beverage  //让espresso 继承beverage 因为espresso是一种饮料 ,具体的被装饰者
    {
        public espresso()
        {
            base.description = "espresso"; //设置饮料的描述在构造函数中,description来自父类
        }
        public double cost()
        {
            return 0.99;
        }
    }

4具体的被装饰者   饮料的调料 

 public class mocha:condimentDecorator  //具体的装饰者 继承装饰者类 而装饰者又继承自 饮料类
    {
        Beverage beverage;//用一个实例变量记录饮料,也就是被装饰者
        public mocha(Beverage beverage)
        {
            this.beverage = beverage;  //让被装饰者记录到实例变量中 ,在构造函数中完成
        }
        public string getDescription()
        {
            return beverage.getDescription() + ","+"mocha";
        }
        public double cost()
        {
            return 0.2 + beverage.cost();//调用委托先计算被装饰者的价钱在加上mocha的加钱等于现在的饮料的价钱
        }
    }
 public class soy:condimentDecorator
    {
       Beverage beverage;//用一个实例变量记录饮料,也就是被装饰者
        public soy(Beverage beverage)
        {
            this.beverage = beverage;  //让被装饰者记录到实例变量中 ,在构造函数中完成
        }
        public string getDescription()
        {
            return beverage.getDescription() + ","+"soy";
        }
        public double cost()
        {
            return 0.11 + beverage.cost();//调用委托先计算被装饰者的价钱在加上mocha的加钱等于现在的饮料的价钱
        }
    }

5 测试一把 

  Beverage bg1 = new espresso();//定一杯espresso不加调料  
            Beverage bg2 = new espresso();
            bg2 = new soy(bg2);//用soy装饰它 ,加soy
            bg2 = new mocha(bg2);//在加mocha,用mocha装饰它
            double cost= bg2.cost();//mocha+soy+espresso 一共的花费

  

  

原文地址:https://www.cnblogs.com/wangjian920110/p/5405141.html