zoukankan      html  css  js  c++  java
  • 装饰者模式

    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 一共的花费

      

      

  • 相关阅读:
    有没有用户体验+UI+前端集于一身的人
    ruby array.count
    ruby subset
    向李刚同学道歉
    rails3转载
    RVM and Capistrano
    paperclip自定制文件名
    ruby爬虫
    rails3已经内置subdomain
    摘录
  • 原文地址:https://www.cnblogs.com/wangjian920110/p/5405141.html
Copyright © 2011-2022 走看看