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

    场景:

    购买咖啡时,可以要求加入各种调料,例如,豆浆,摩卡

    豆浆,摩卡就是装饰者,咖啡是被装饰者。

    不好的设计:

    问题:

    1、一旦出现新的调料,我们就需要加上新的方法,并改变超类中的cost方法

    2、以后可能开发新的饮料,对这些饮料(冰茶),某些调料可能并不合适,但是在这个设计中,Tea子类

    仍将继承那些不合法的方法,例如 奶泡。

    3、万一顾客想要双倍摩卡,怎么办?

    装饰者和被装饰者必须是一样的类型,也就是有共同的超类,这是相当关键的地方。
    在这里,我们利用继承达到“类型匹配”,而不是利用继承获得“行为”。

    当我们将装饰者与组件组合时,就是在加入新的行为,所得到的新行为,并不是继承自
    超类,而是由组合对象而来。

    我们可以在任何时候,实现新的装饰者增加新的行为。如果依赖继承,每当需要新行为时,
    还得修改现有的代码。

    类图:

    //超类(抽象组件)

    public abstract class Beverage{

      String description = "Unknown Beverage";

       public String getDescription()

      {

        return description;

      }

      public abstract double cost();

    }

    //抽象装饰者(调料)

    public abstract class CondimentDecorator extends Beverage{

      public abstract  String getDescription();

    }

    //饮料(具体组件)

    public class Espresso extends Beverage{

       public Espresso ()

      {

        description = "Espresso";

      }

      public double cost()

      {

        return 1.99;

      }

    }

    //调料(具体装饰者)

    public class Mocha extends CondimentDecorator {

      Beverage beverage;//用一个实例变量记录饮料,也就是被装饰者

       public Mocha (Beverage beverage )

      {

        this.beverage = beverage;

      }

      public String getDescription()

      {

        return beverage.getDescription() + ", Mocha";

      }

      public double cost()

      {

        return 1.99 + beverage.cost();

      }

    }

    摩卡(Mocha)是一个装饰者,所以让它扩展自CondimentDecorator 

    CondimentDecorator 扩展自Beverage 

    ----------------------------------------------------------------------------

    测试代码

    public static void main(String[] args)

    {

      Beverage  beverage  =  new Espresso();//一杯espresso

      beverage  = new  Mocha(beverage); //加入调料摩卡

      beverage  = new  Mocha(beverage); //再加入一份摩卡

      //加了两份摩卡的espresso的价格

      double price = beverage .cost();

    }

    要点:

    在我们的设计中,应该允许行为可以被扩展,而无须修改现有的代码。

    装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得复杂。

    在选择需要被扩展的代码部分时要小心。每个地方都采用开发-关闭原则,是一种浪费,

    也没必要,还会导致代码变得复杂且难以理解。

  • 相关阅读:
    Alpha冲刺(5/10)
    Alpha冲刺(4/10)
    团队现场编程
    关于合同标准形的专题讨论
    关于相似标准形的专题讨论
    关于数学分析的计算题I(积分)
    关于数学分析的证明题III(级数)
    关于数学分析的证明题II(微分)
    关于数学分析的证明题I(积分)
    关于反常积分收敛的专题讨论
  • 原文地址:https://www.cnblogs.com/zhangxuan/p/8350643.html
Copyright © 2011-2022 走看看