Composite概述
可以使用一种对客户端***透明的方式***来动态的扩展对象的功能
是***继承关系***的替代方案之一
- 定义
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活
- 使用场景
需要透明且动态的扩展类功能时
- 装饰模式的UML图
Component 抽象组件
可以是一个接口或者抽象类,作为被装饰的原始对象
ConcreteComponent 组件具体实现类
抽象类的基本实现,装饰类的具体实现
Decorator 抽象装饰者
承担的职责是为了装饰我们的组件对象,其内部一定要有一个指向组件对象的引用,在大多数情况下,该类为抽象类,需要根据不同的装饰逻辑实现不同的具体子类,当然如果装饰逻辑单一,只有一个的情况下,我们可以省略该类直接作为具体的装饰者.
ConcreteDecoratorA ConcreteDecoratorB 装饰者具体实现类
对抽象装饰者进行具体实现
ComponentClient 客户类
代码
ConcreteComponent
public abstract class Component {
/**
* 生成抽象方法,可以生成多个
*/
public abstract void opertate();
}
Decorator
public abstract class Decorator extends Component { private Component component; /** * 必须构造一个方法 需要一个component类型对象 * * @param component */ public Decorator(Component component) { this.component = component; } @Override public void opertate() { component.opertate(); } }
ConcreteDecoratorApublic class ConcreteDecoratorA extends Decorator { public final String TAG=ConcreteDecoratorA.class.getSimpleName()+"======"; /** * 必须构造一个方法 需要一个component类型对象 * * @param component */ public ConcreteDecoratorA(Component component) { super(component); } @Override public void opertate() { operateA(); super.opertate(); operateB(); } public void operateA() { System.out.println(TAG+"operateA"); } public void operateB() { System.out.println(TAG+"operateB"); } }
ConcreteDecoratorB
public class ConcreteDecoratorB extends Decorator {
public final String TAG = ConcreteDecoratorB.class.getSimpleName() + "======";
/**
* 必须构造一个方法 需要一个component类型对象
*
* @param component
*/
public ConcreteDecoratorB(Component component) {
super(component);
}
@Override
public void opertate() {
operateB();
super.opertate();
operateA();
}
public void operateA() {
System.out.println(TAG + "operateA");
}
public void operateB() {
System.out.println(TAG + "operateB");
}
}
ComponentClient 客户端
public class ComponentClient {
public static void main(String[] args) {
Component component=new ConcreteComponent();
Decorator decoratorA=new ConcreteDecoratorA(component);
decoratorA.opertate();
Decorator decoratorB=new ConcreteDecoratorB(component);
decoratorB.opertate();
}
}
[对比]代理模式和装饰者模式
相同点
装饰者(decorator)和被装饰者(decoratee)都实现同一个 接口。对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。此外,不论我们使用哪一个模式,都可以很容易地在真实对象的方法前面或者后面加上自定义的方法。
差异
装饰器模式关注于在一个对象上动态的添加方法,然而理模式关注于控制对对象的访问。换句话说,用代理模式,代理类(proxy class)可以对它的客户藏一个对象的具体信息。因此,当使用代理模式的时候,我常常在一个代理类中创建一个对象的实例。并且,当我们使装饰器模 式的时候,我们通常的做法是将原始对象作为一个数传给装饰者的构造器。
[总结]
使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。
Android源码设计模式解析与实战