装饰模式
定义: 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活.
在不必改变类文件和使用继承的情况下,动态地扩展一个对象的功能,及继承的替代方案之一.
使用场景:
- 在不影响其他对象的情况下,以动态,透明的方式给单个对象添加职责.
- 需要动态地给一个对象增加功能,这些功能可以动态地撤销.
- 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时.
优点:
- 通过组合而非继承的方式,动态地扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为.
- 有效避免了使用继承的方式扩展对象功能而带来的灵活性差,子类无限制扩张的问题.
- 具体组件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体组件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合"开放封闭原则".
缺点:
- 因为所有对象均继承于 Component ,所以如果 Component 内部结构发生变化,则不可避免地影响所有子类(装饰者和被装饰者),如果基类改变,则势必影响对象的内部.
- 比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也比较困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐.所以,只在必要的时候使用装饰模式.
- 装饰层数不能过多,否则会影响效率.
例子说明:
//抽象组件类
public abstract class Component {
/**
* 抽象的方法,这个随你做,
* 同样地你也可以增加更多的抽象方法
* */
public abstract void operate();
}
//组件具体实现类
public class ConcreteComponent extends Component{
@Override
public void operate() {
//具体逻辑自己搞.
}
}
//抽象装饰类
public abstract class Decorator extends Component{
private Component component;//持有一个Component 对象的引用
//必要的构造方法,需要一个Component类型的对象
public Decorator(Component component) {
this.component = component;
}
@Override
public void operate() {
component.operate();
}
}
public class ConcreteDecoratorA extends Decorator{
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void operate() {
super.operate();
operateA();
operateB();
//调用顺序根据自己需要来搞
}
//自定义的装饰方法A
public void operateA(){
//装饰方法逻辑
}
//自定义的装饰方法B
public void operateB(){
//装饰方法逻辑
}
}
public static void main(String[] args) {
//构造被装饰的组件对象
Component component = new ConcreteComponent();
//根据组件对象构造装饰者对象A并调用,此时相当于给组件对象增加装饰者A 的功能方法.
Decorator decorator = new ConcreteDecoratorA(component);
decorator.operate();
}
在 Android 源码中,有很许多 装饰模式,比如 Context 类,比如 startActivity() 往上回溯,最终和可以回溯到 ContextWrapper 类,这个类里有 Context 的引用.这就是装饰模式.跟着源码看看吧.