一、介绍,定义
又称为包装模式,结构性设计模式。
使用一种对客户端透明的方式来动态地扩展对象的功能,同时它也是继承关系的一种替代方案。
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
二、使用场景
需要透明地、动态地扩展类的功能时,装饰模式不失一种理想方案。
三、UML类图
Component:抽象组件可以是一个接口或者抽象类,充当被装饰的原始对象。
ConcreteComponent:组件具体实现类该类是 Component 类的基本实现,也是我们装饰的具体对象。
Decorator:抽象装饰者其承担的职责是为了装饰我们的组件对象,其内部一定要有一个指向组件对象的引用。
ConcreteDecorator:抽象装饰者对抽象装饰者做出具体实现。
四、通用代码
// 抽象组件类
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 类型的对象
* @param component Component 对象
*/
public Decorator(Component component) {
this.component = component;
}
@Override public void operate() {
component.operate();
}
}
// 装饰者具体实现类
public class ConcreteDecoratorA extends Decorator {
protected ConcreteDecoratorA(Component component) {
super(component);
}
@Override public void operate() {
operateA();
super.operate();
operateB();
}
public void operateA() {
// 自定义的装饰方法 A
// 装饰方法逻辑
}
public void operateB() {
// 自定义的装饰方法 B
// 装饰方法逻辑
}
}
// 客户端实现
public class Client {
public static void main(String[] args) {
// 构造被装饰的组件对象
Component component = new ConcreteComponent();
// 根据组件对象构造装饰者对象并调用,即给组件对象增加装饰者的功能方法
Decorator.decoratorA = new ConcreteDecoratorA(component);
decoratorA.operate();
Decorator.decoratorB = new ConcreteDecoratorB(component);
decoratorB.operate();
}
}
五、简单实现
其实装饰模式并不复杂,也不陌生,它就是一种 类间的封装,例如我们常在 Activity 的 onCreate() 方法中做一些相关的初始化操作。
public class DecoratorActivity extends Activity {
@Override
protected void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
initViews();
findViews();
setListeners();
}
private void initViews() {
setContentView(R.layout.activity_main);
}
private void findViews() {
// 匹配组件
}
private void setListeners() {
// 设置组件的监听器
}
}
六、模式的优缺点:
装饰模式与代理模式的区别 (容易混淆)
装饰模式:以对客户端透明的方式 扩展对象的功能,即继承关系的一个替代方案。
代理模式:给一个对象提供一个代理对象,并由 代理对象 来控制对原有对象引用。
装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,但不对对象本身的功能进行增强。