Decorator模式:动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案。
一. 基本概念:
1.设计原则:
(1) 多用组合,少用继承。
利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。
(2)类应设计的对扩展开放,对修改关闭。
目标是允许类容易扩展,在不修改现有代码的情况下,就可搭配新的行为。
开放-关闭原则,需集中在设计中最有可能改变的地方,因为它通常会引入新的抽象层次。
2.特点:
(1) 装饰模式中使用继承的目的是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为,行为来自于装饰者和基本组件。只有类型一样了才能被多次装饰。
(2) 装饰者和被装饰对象有相同的超类型。
(3) 对象可以在任何时候被装饰,是在运行时动态的,不限量的被装饰,比继承更多的灵活性,可以创造出很多不同行为的组合。
(4)装饰者设计更加复杂性。且会出现许多小类,如果过度使用,会使程序变得很复杂。
二. 实例
不同饮料、不同调料动态地组合
1. Beverage类:饮料抽象组件
饮料的基类,可把他看为一个接口;包括一个抽象类,和一个抽象方法,这个基类可以被装饰者继承装饰。
public abstract class Beverage { String description = "Unknown Beverage"; public String getDescription() { return description; //可以被装饰者覆盖 } public abstract double cost(); }
浓缩果汁类:饮料具体组件
具体饮料,扩展自Beverage类,加上自己的属性。
public class Espresso extends Beverage { public Espresso() { description = "Espresso";//通过构造器设置饮料的描述,description 继承自父类。 } public double cost() { return 1.99; } }
2. Condiment类:调料抽象组件
调料抽象基类,可把他看为一个接口;属于装饰者类,要扩展自Beverage类;
public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); }
具体装饰者类:调料具体组件
扩展自调料基类。
public class Mocha extends CondimentDecorator { public Mocha(Beverage beverage) { this.beverage = beverage;//作为构造器参数,让被装饰者记录到实例变量中, } public String getDescription() { return beverage.getDescription() + ", Mocha"; } public double cost() { return beverage.cost() + .20; } }
3.测试类:
public class StarbuzzCoffee { public static void main(String args[]) { Beverage beverage = new Espresso();//一杯Espresso饮料,不需要调料 beverage1 = new Mocha(beverage);//带Mocha调料的Espresso饮料 beverage2 = new Whip(beverage1);//带Mocha和Whip调料的Espresso饮料 System.out.println(beverage2.getDescription() + " $" + String.format("%.2f", beverage2.cost())); } }
三. java I/O
java.io类就采用了装饰者模式,