设计模式之装饰者模式

2017-09-24  本文已影响0人  yaSecrets

模拟需求

更新一个订单系统,以满足饮料供应要求。
原先的设计是这样的

图片.png

每种饮料都需要实现cost抽象方法,来返回饮料的价钱。购买咖啡时也可以要求在其中加入各种调料,商家会根据不同的调料收取不同的费用。
如果这样设计:

图片.png

这简直是“类爆炸”,基类中加入了新的功能并不适用于所有的子类,给维护造成了很大的困难,而且也不能应对需求的变化。继承是一种强耦合,在编译时就动态决定的,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。

类应该对扩展开放,对修改关闭。

定义装饰者模式

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

图片.png

装饰饮料

图片.png

不难发现,装饰者和被装饰者都继承了同一个抽象类。当我们将装饰者与组件组合时,就是在加入新的行为,所得到的行为不是继承于超类,而是由组合对象得来的。装饰类继承于抽象类,是为了有正确的类型,而不是继承它的行为。

代码实现

public abstract class Beverage{
  String description = "Unknow Beverage';
  public String getDescription(){
    return description;
  }
  public abstract double cost();
}
//Condiment(调料)装饰抽象类
public abstract class CondimentDecorator extends Beverage{
  //所有的调料必须重新实现getDescription方法
  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 beveragge.getDescription() + ",Mocha";
  }
  pubic double cost(){
    //要计算带Mocha饮料的价钱,首先把调用方法委托给被装饰对象计算,再加上Mocha的价钱
    return 20 + beverage.cost;
  }
}
//产生订单
public static void main (String[] args){
  //制造一个饮料
  Beverage beverage = new darkRoast();
  //用Mocha装饰对象
  beverage = new Mocha(beverage);
  //用whip装饰对象
  beverage = new Whip(beverage);
  system.out.println(beverage.getDescription()+"$"+beverage.cost());
}

jdk中的装饰类:java/Io

图片.png

BufferedInputStream和LineNumberInputStream都扩展自FilterInputStream,而FileInputStream是一个抽象的装饰类

图片.png
上一篇下一篇

猜你喜欢

热点阅读