简介
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装,动态的将责任附加到对象上,在拓展功能时,提供了比继承更有弹性的替代方案。
装饰器模式由组件和装饰者组成:
抽象组件(Component):需要装饰的抽象对象。
具体组件(ConcreteComponent):是我们需要装饰的对象
抽象装饰类(Decorator):内含指向抽象组件的引用及装饰者共有的方法。
具体装饰类(ConcreteDecorator):负责给构件对象添加新的责任。
类图
代码
/**
* 抽象组件(Component):饮料
* 可以使接口,也可以是抽象类
* @author: 张彬
* @date: 2018年5月29日 上午10:49:10
* @version: V1.0
* @review: 张彬/2018年5月29日 上午10:49:10
*/
public interface Beverage {
public String getDesc() ;
public double cost();
}
/**
* 具体组件(ConcreteComponent):纯咖啡
* @author: 张彬
* @date: 2018年5月29日 上午11:10:51
* @version: V1.0
* @review: 张彬/2018年5月29日 上午11:10:51
*/
public class Espresso implements Beverage{
@Override
public double cost() {
return 21.5;
}
@Override
public String getDesc() {
return "Espresso";
}
}
/**
* 抽象装饰类(Decorator):调料
* @author: 张彬
* @date: 2018年5月29日 上午11:02:26
* @version: V1.0
* @review: 张彬/2018年5月29日 上午11:02:26
*/
public abstract class Condiment implements Beverage{
protected Beverage beverage;
public Condiment(Beverage beverage) {
this.beverage = beverage;
}
}
/**
* 具体装饰类(ConcreteDecorator):糖
* @author: 张彬
* @date: 2018年5月29日 上午11:09:45
* @version: V1.0
* @review: 张彬/2018年5月29日 上午11:09:45
*/
public class Suger extends Condiment {
public Suger(Beverage beverage){
super(beverage);
}
@Override
public String getDesc() {
return beverage.getDesc() + ",Suger";
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
/**
* 具体装饰类(ConcreteDecorator):奶
* @author: 张彬
* @date: 2018年5月29日 上午11:06:09
* @version: V1.0
* @review: 张彬/2018年5月29日 上午11:06:09
*/
public class Milk extends Condiment{
public Milk(Beverage beverage){
super(beverage);
}
@Override
public String getDesc() {
return beverage.getDesc() + ",Milk";
}
@Override
public double cost() {
return 0.5 + beverage.cost();
}
}
/**
* 测试:假设我们现在去咖啡店要了一杯咖啡,可以加奶、加糖等等。咖啡和奶、糖分别有不同的价格。
* 咖啡就是我们的组件,奶和糖是我们的装饰者,现在我们要计算调制这样一杯咖啡花费多少
* @author: 张彬
* @date: 2018年5月29日 上午11:19:35
* @version: V1.0
* @review: 张彬/2018年5月29日 上午11:19:35
*/
public class Client {
public static void main(String[] args) {
Beverage beverage = new Espresso();
beverage = new Milk(beverage);
beverage = new Suger(beverage);
System.out.println(beverage.getDesc() + "¥" + beverage.cost());
}
}
输出结果:
Espresso,Milk,Suger¥23.0
总结
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂
应用实例:java.io