定义
动态的给一个对象添加一些额外的职责。就功能来说,装饰模式相比生成子类更加灵活
使用场景
- 装饰类和被装饰类都可以独立发展,不会耦合,它是继承关系的一个替代方案
- 需要扩展一个类的功能,或者给一个类增加附加功能
- 动态增加一个类的功能,再动态的撤销
- 需要为一批兄弟类,进行改装或者加装功能首选装饰模式
实现方式
组件接口
/**
* 基础接口
**/
public interface Component {
public void operate();
}
组件实现类
/**
* 具体实现类
**/
public class ConcretComponent implements Component {
public void operate() {
System.out.println("ConcretComponent operate");
}
}
装饰类
/**
* 装饰类
**/
public class Decorator implements Component {
public Component component;
public Decorator(Component component) {
this.component = component;
}
public void operate() {
this.component.operate();
}
}
具体装饰类
/**
* 具体装饰类
**/
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operate() {
System.out.println("ConcreteDecorator operate");
this.component.operate();
}
}
扩展与思考
-
代理模式和装饰器模式的区别。对于代理类,如何调用对象的某一功能是思考重点,而不需要兼顾对象的所有功能;对于装饰类,如何扩展对象的某一功能是思考重点,同时也需要兼顾对象的其它功能,因为再怎么装饰,本质也是对象本身,要担负起对象应有的职责。
-
JDK
的java.io
流就是用了装饰器模式,对InputStream
进行增强。可以对流分为三层。第一层:
Reader、Writer、InputStream、OutputStream
,对应抽象的接口第二层:
FilterOutputStream
、FilterInputStream
、FilterWriter
、FilterReader
这些带有Filter的类对应抽象的装饰者,这里也不一定要使用接口和抽象类,比如FilterOutputStream
就是具体的实现类。这也属于装饰器模式。另外InputstreamReader
也可以算抽象的装饰者,只是这里只对StreamDecoder
类型进行装饰。第二层其他:第二层中除了上述提到的5个类,其他的都可以看做是具体的被装饰者。
第三层:第三层都是具体的装饰者 比如:
PrintStream
、DateOutputStream
、BufferInputSteam
等。可以使用这些装饰器,对第二层中的类进行装饰。 -
HttpServletRequestWrapper
也是装饰类,继承该类可以实现对某些敏感字眼的过滤功能。