装饰者模式

场景:

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

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

 

不好的设计:

 

问题:

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();

}

要点:

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

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

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

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

 

转载于:https://www.cnblogs.com/zhangxuan/p/8350643.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值