定义
动态的给一个对象添加一些额外的职责。就功能来说,装饰模式相比生成子类更加灵活
使用场景
- 装饰类和被装饰类都可以独立发展,不会耦合,它是继承关系的一个替代方案
- 需要扩展一个类的功能,或者给一个类增加附加功能
- 动态增加一个类的功能,再动态的撤销
- 需要为一批兄弟类,进行改装或者加装功能首选装饰模式
实现方式
组件接口
/** * 基础接口 **/ 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
也是装饰类,继承该类可以实现对某些敏感字眼的过滤功能。