简介
装饰器模式(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"; } }
/** * 具体装饰类(ConcreteDecorator):糖 * @author: 张彬 * @date: 2018年5月29日 上午11:09:45 * @version: V1.0 * @review: 张彬/2018年5月29日 上午11:09:45 */ public class Suger extends Condiment { private Beverage beverage; public Suger(Beverage beverage){ this.beverage = 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{ private Beverage beverage; public Milk(Beverage beverage){ this.beverage = 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