1 介绍
装饰者,又名包装器(wrapper)。以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
1.1 什么是装饰者模式
装饰者动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
1.2 解决什么样的问题
我们希望给某个对象而不是整个类添加一些功能。
或者,我们需要把所需的功能按正确的顺序串联起来进行控制。
2 原理
2.1 uml图
image.png
装饰者模式的主要角色有
Component:抽象组件,一个抽象接口,以规范准备接受附加责任的对象。
ConcreteComponent:具体组件。定义一个将要接受附加责任的类。
Decorator:装饰者。持有一个Component对象的实例,并定义一个与抽象组件接口一致的接口。
ConcreteDecorator:具体装饰者。负责给组件对象"贴上"附加的责任。
2.2 代码示例
Component代码示例
public class Decorator implements Component {
private Component component;
/**
* 构造方法
*/
public Decorator(Component component){
this.component = component;
}
/**
* 构造方法
*/
public Decorator(){
//code
}
/**
* 业务方法,委派给component
*/
@Override
public void sampleOperation() {
component.sampleOperation();
}
}
ConcreteComponent代码示例
public class ConcreteComponent implements Component {
@Override
public void sampleOperation() {
System.out.println("this is ConcreteComponent");
}
}
Decorator代码示例
public class Decorator implements Component {
private Component component;
/**
* 构造方法
*/
public Decorator(Component component){
this.component = component;
}
/**
* 构造方法
*/
public Decorator(){
}
/**
* 业务方法,委派给component
*/
@Override
public void sampleOperation() {
component.sampleOperation();
}
}
ConcreteDecorator代码示例
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void sampleOperation() {
System.out.println("this is ConcreteDecoratorA");
super.sampleOperation();
}
}
调用示例
public static void main(String[] args) {
Component component = new ConcreteDecoratorA(new ConcreteComponent());
component.sampleOperation();
}
运行结果
this is ConcreteDecoratorA
this is ConcreteComponent
2.3 优缺点
-
优点
-
把类中的装饰功能从类中搬移去除,这样可以简化原有的类。
-
有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。
-
缺点
-
如果功能拓展太多,将产生大量的类。
-
多层装饰会变得复杂。。
3 适用场景
在以下情况下应当使用装饰模式:
(1)需要扩展一个类的功能,或给一个类增加附加责任。
(2)需要动态地给一个对象增加功能,这些功能可能再动态地撤销。
(3)不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
真实世界的装饰: Java I/O。
4 总结
装饰模式是为已有功能动态地添加更多功能的一种方式。
- 注意事项与要点
- 抽象装饰器与具体被装饰对象实现同一个接口。
- 抽象装饰器持有被装饰器接口对象,以便请求传递。
- 具体装饰器需要重写抽象装饰器的方法并引用super进行调用,转发请求。
参考书籍及文章
- 《大话设计模式》,清华大学出版社,程杰
- 《设计模式——可复用面向对象软件的基础》,机械工业出版社,Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides
3.《Java与模式》,电子工业出版社,阎宏
4.《Head First 设计模式(中文版)》,中国电力出版社
5.《设计模式-装饰器模式》,https://juejin.im/post/5cfc8e37f265da1b667bcd5b?utm_source=gold_browser_extension











网友评论