一、适配器模式
适配器就是把一个类的接口变换成客户端所能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作。通常被用于在一个项目需要引用一些开源框架在一起工作的情况下,这些框架的内部都有一些关于环境信息的接口,需要从外部传入,但是外部的接口不一定能够匹配,在这种情况下,就需要适配器模式来转换接口。
1、适配器模式的类结构
Target(目标接口):客户端期待的接口;
Adaptee(源接口):需要被适配的接口;
Adapter(适配器):将源接口适配成目标接口,继承源接口,实现目标接口。
2、Java I/O中的适配器模式
InputStreamReader和OutputStreamWriter类分别继承了Reader和Writer接口,但是要创建它们的对象必须在构造函数中传入一个InputStream和OutputStream的实例。InputStreamReader实现了Reader接口,并且持有了InputStream的引用,这里是通过StreamDecoder类间接持有的,因为从byte到char需要经过编码。很显然,适配器就是InputStreamReader类,源接口就是InputStream,目标接口就是Reader类。OutputStreamWriter也是类似的方式。
二、装饰器模式
装饰器模式,顾名思义,就是将某个类重新装扮一下,让它的功能变得更加强大,但是作为原来这个类的使用者,还不应该感受到装饰前和装饰后有什么不同,否则就破坏了原有类的结构,所以装饰器模式要做到对被装饰类的使用者透明,这是对装饰器模式的一个要求。
1、装饰器模式的类结构
Component:抽象组件角色,定义一组抽象的接口,规定这个被装饰组件都有哪些功能;
ConcreteComponent:实现这个抽象组件的所有功能;
Decorator:装饰器角色,它持有一个Component对象实例的引用,定义一个与抽象组件一致的接口;
ConcreteDecorator:具体的装饰器实现者,负责实现装饰器角色定义的功能。
2、Java I/O中的装饰器模式
以FileInputStream为例,InputStream类就是以抽象组件存在的,而FileInputStream就是具体组件,它实现了抽象组件的所有功能。FilterInputStream类无疑就是装饰角色,它实现了InputStream类的所有功能,并且持有InputStream对象实例的引用。BufferedInputStream是具体的装饰器实现者,它给InputStream类附加了功能。这个装饰器类的作用就是使得InputStream读取的数据保存在内存中,从而提高读取的性能。与这个装饰器类有类似功能的是LineNumberInputStream类,它的作用就是提高按行读取数据的功能。
3、适配器模式与装饰器模式的区别
适配器模式和装饰器模式都有一个别名,就是包装模式,它们看似都是起到包装一个类或对象的作用,但是使用它们的目的很不一样。适配器模式是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的;而装饰器模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方法从而提升性能。