适配器模式
把一个类的接口变换成客户端所能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作。
通常被用在一个项目需要引用一些开源框架来一起工作的情况下,这些框架的内部都有一些关于环境信息的接口,需要从外部传入,但是外部接口不一定能匹配,在这种情况下,就需要适配模式来转换接口。
适配器模式的结构
适配器模式类结构图:
- Target(目标接口):所要转换的所期待的接口。
- Adaptee(源角色):需要适配的接口。
- Adapter(适配器):将源接口适配成目标接口,继承源接口,实现目标接口。
Java I/O 中的适配器模式
InputStreamReader 类结构图:
InputStreamReader 实现了 Reader 接口(抽象类),通过在构造方法中传入 InputStream 的实例,持有 InputStream 的引用,通过 StreamDecoder 类间接持有的,因为从 byte 到 char 要经过编码。
InputStreamReader 的作用就是将 InputStream 适配到 Reader。其中适配器就是 InputStreamReader 类,源角色就是 InputStream 代表的实例对象,目标接口就是 Reader 类,OutputStreamWriter 类也是类似的方式。
在 I/O 类库中还有很多,如 StringReader 将一个 String 类适配到 Reader 接口,ByteArrayInputStream 适配器将 byte 数组适配到 InputStream 流处理接口。
装饰器模式
装饰器模式的目的就是将某个类重新装扮一下,使其功能更强大,但做为原来这个类的使用者不应该感受到装饰前和装饰后有什么不同,否则就破坏了原有类的结构。要做到对被装饰类的使用者透明。
装饰器模式的结构
- Component 抽象组件角色,定义一组抽象接口,规定被装饰组件都有哪些功能。
- ConcreteComponent 具体组件,实现这个抽象组件的所有功能。
- Decorator 装饰器角色,持有一个 Component 对象实例的引用,定义一个与抽象组件一致的接口。
- ConcreteDecorator 具体的装饰器实现者,负责实现装饰器角色定义的功能。
Java I/O 中的装饰器模式
BufferedInputStream 类结构图:
其中 InputStream (Component),抽象组件角色,FileInputStream 具体组件,实现了 InputStream 所有功能。 FilterInputStream 装饰器角色,实现了 InputStream 所有功能并持有 InputStream 对象实例的引用。BufferedInputStream 具体的装饰器实现者,它给 InputStream 附加了功能,使 InputStream 读取的数据保存在内存中,并提高读取的性能。
适配器模式与装饰器模式区别
二者都属于包装模式(Wrapper),但目的不同。适配器模式的意义是要将一个接口转变成另外一个接口,它的目的是通过改变接口达到重复使用的目的;而装饰器模式是保持原有接口,增加原有对象的功能,或改变原有对象处理方法提升性能。
参考
- 《深入分析Java Web技术内幕》(修订版) 许令波 著