(《设计模式解析与实战——何红辉,关爱民》读书笔记)
一、定义
动态的给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
比如,女人穿衣服,每天换着各种不同的衣服,但是不管穿成什么样,她还是她,其本质是不变的。
二、使用场景
需要透明且动态的扩展类的功能时。
三、装饰模式的通用代码
/**
* 抽象组件类:可以为一个接口或抽象类,其充当的就是被装饰的原始对象
*/
public abstract class Compent {
/**
* 抽象的方法,这个随你做。同样的你也可以增加更多的抽象方法
*/
public abstract void operate();
}
/**
* 组件具体实现类:该类是Compent类的具体实现类,也是我们装饰的具体对象
*/
public class ConcreteCompent extends Compent{
@Override
public void operate() {
// TODO 具体逻辑,这个随你做
System.out.println("该类对象的共同逻辑");
}
}
/**
* 抽象装饰者:装饰组件对象,其内部一定要有一个指向组件对象的引用。
*/
public abstract class Decorator extends Compent {
private Compent mCompent;
/**
* 必要的构造方法,需要一个Compent对象
* @param compent
*/
public Decorator(Compent compent) {
this.mCompent = compent;
}
@Override
public void operate() {
mCompent.operate();
}
}
/**
* 装饰者具体实现类A:只是对抽象装饰者做出具体的实现
*/
public class ConcreteDecoratorA extends Decorator {
protected ConcreteDecoratorA(Compent compent) {
super(compent);
}
@Override
public void operate() {
// 装饰方法既可在父类方法前调用也可在之后调用
operateA();
super.operate();
}
/**
* 自定义的装饰方法A
*/
private void operateA() {
// TODO 装饰方法逻辑
System.out.println("装饰方法A的逻辑");
}
}
/**
* 装饰者具体实现类B:只是对抽象装饰者做出具体的实现
*/
public class ConcreteDecoratorB extends Decorator {
protected ConcreteDecoratorB(Compent compent) {
super(compent);
}
@Override
public void operate() {
// 装饰方法既可在父类方法前调用也可在之后调用
operateB();
super.operate();
}
/**
* 自定义的装饰方法B
*/
private void operateB() {
// TODO 装饰方法逻辑
System.out.println("装饰方法B的逻辑");
}
}
package com.decorator.pattern;
/**
* 客户调用类
*/
public class Client {
public static void main(String[] args) {
// 构造被装饰的组件对象
Compent compent = new ConcreteCompent();
// 根据组件对象构造装饰者对象A并调用,此时相当于给组件对象增加装饰者A的功能方法
Decorator decoratorA = new ConcreteDecoratorA(compent);
decoratorA.operate();
System.out.println("==============");
// 根据组件对象构造装饰者对象B并调用,此时相当于给组件对象增加装饰者B的功能方法
Decorator decoratorB = new ConcreteDecoratorB(compent);
decoratorB.operate();
}
}
运行结果:
四、总结
装饰模式在Android中最大的体现就是Context了,Context本质就是一个抽象类,在其内部定义了大量的抽象方法,比如startActivity方法,而其真正的实现是在ContextImpl中完成的。
装饰模式和代理模式有点类似。其区别是:
(1)装饰模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案;而代理模式则是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用。
(2)装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,但不对对象本身的功能进行增强。