意图
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活。装饰模式又称包装器Wrapper。
结构
实现
- Component(抽象构件),定义一个对象接口,可以给这些对象动态地添加职责,它是具体构件和抽象装饰类的共同父类。
- ConcreteComponent(具体构件),它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。
- Decortor(抽象装饰类),维持了一个Component引用,并定义了一个与Component 接口一致的接口。
- ConcreteDecortor(具体装饰类),它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。
我们先来定义Component,可以是接口或者抽象类
public interface Component {
void operation();
}
接下来是ConcreteComponent ,是 Component 的实现类
public class ConcreteComonpent implements Component{
@Override
public void operation() {
System.out.println("This is the Concrete Component");
}
}
其次是 Decortor 类,这里维持了一个 Component 的引用,可以通过 set 方法 或者构造方法等等。
public abstract class Decorator implements Component{
protected Component component;
public void setComponent(Component component) {
this.component = component;
}
@Override
public void operation() {
if(component != null){
component.operation();
}
}
}
最后是我们的 ConcreteComponentA 和 ConcreteComponentB 类,它们都是具体的装饰对象,起到给Component 添加职责的功能。
public class ConcreteDecoratorA extends Decorator{
private String addState;
@Override
public void operation() {
super.operation();
addState = "New state"; //进行装饰
System.out.println("This is the ConcreteDecoratorA," + addState);
}
}
public class ConcreteDecoratorB extends Decorator{
@Override
public void operation() {
super.operation();
addedBehavior(); //进行装饰
System.out.println("This is the ConcreteDecoratorB");
}
private void addedBehavior(){
System.out.println("addedBehavior");
}
}
装饰模式在 Android 中的应用 —— Context,作为一名 Android 开发者,Context 应该是再也熟悉不过的了。我们平常用的最多的 startActivty 方法就是这个类当中的。首先,我们来看一下 Context 的继承结构。
简直和上图的装饰模式 UML 一模一样。
- Context 对应着 Component
- ContextImpl 对应着 ConcreteComponent
- ContextWraper 对应着 Decorator
- Activity、Application、Service、ContextThemeWrapper 对应着 ConcretDecorator。
参考资料
[1] PleaseCallMeCoder. 从装饰者模式到Context类族
[2] Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides. 设计模式:可复用面向对象软件的基础[M]. 李英军等译.北京:机械工业出版社,2009.
[3] 程杰. 大话设计模式[M]. 北京 : 清华大学出版社 , 2007.