装饰者模式
2016-11-23 本文已影响0人
olivia_ong
定义
装饰者模式动态地将责任附加到对象上,若要扩展功能,装饰者模式提供了比继承更有弹性的替代方案。
简而言之,如果你想扩展对象的功能但是有不修改对象内部结构可以使用装饰者模式。
类图
装饰者模式类图其中涉及到的类有:
- 抽象组件类(Component):被装饰者和装饰者类都继承该接口。
- 具体组件(ConcreteComponent)类:定义具体的装饰组件。
- 装饰者(Decorator)类:定义一个装饰者类的接口,所有装饰都继承该类。
- 具体装饰者(ConcreteDecorator)类:负责给被装饰者扩展功能。
从类图中我们可以发现,装饰者类和被装饰者组件都是继承同一接口,在客户端并不会觉得对象在装饰前和装饰后有何不同,任何需要被装饰组件的场合都可以用装饰后的对象进行代替。
实例
假设一个咖啡店,可以根据顾客的要求添加各种不同的材料做成咖啡,不同的成分有不同的价格,需要计算最后咖啡的价格。我们可以利用装饰者模式进行设计。
代码:
public abstract class Beverage {//Component类
String description="Unknown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
public class HouseBlend extends Beverage{//ConcreteComponent类
public HouseBlend(){
description="House Blend Coffee";
}
public double cost(){
return .89;
}
}
public abstract class CondimentDecorator extends Beverage {//Decorator类
public abstract String getDescription();
}
public class Mocha extends CondimentDecorator{//ConcretedDecorator类
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage=beverage;
}
public String getDescription(){
return beverage.getDescription()+",Mocha";
}
public double cost(){
return .20+beverage.cost();
}
}
public class StarBuzzCoffee {
public static void main(String[] args) {
Beverage beverage=new HouseBlend();//创建被装饰组件
beverage=new Mocha(beverage2);//加上装饰
System.out.println(beverage.getDescription()+" $"+beverage.cost());
}
}
扩展
- 从上面的实例我们可以想到,装饰者模式的一个缺点就是会产生很多小的类,咖啡种类繁多,每种都是一个独立的类,可以添加的东西也很多,每种都会是一个装饰者子类。同时,有些代码会依赖特定的类型,导入装饰者会发生错误。
- java JDK中典型地使用装饰者模式的有:Java I/O。例如BufferedInputStream就是FileInputStream的装饰者类,加入了readLine()以及其他方法进行扩展。