设计模式解析–适配器模式
- 对适配器模式功能比较好理解,就是讲一个类的接口换成客户端所能接受的另外一个接口,从而使两国接口不匹配而无法在一起工作的两个类能在一起工作。
适配器的结构
-
适配器UML图如下
-
Target(目标接口):需要转换的接口
-
Adaptee(源角色):需要适配的类或接口
-
Adapter(适配器):将接口适配成目标接口,继承源接口,实现目标接口。
-
如下一个简单案例
//目标接口
public interface FlyTarget {void canFly();
}
//需要适配的类
public class Flying {public void fly() {System.out.println("i can flay");}
}
//代理实现
public class Bird extends Flying implements FlyTarget {@Overridepublic void canFly() {System.out.println("i am bird");fly();System.out.println("over flay,i am walk");}
}
- 如上我们利用 Flying 来实现鸟这个类的FlyTarget
Java I/O 中的适配器模式
- 适配器将一个接口适配到另外一个接口,在Java I/O中比较多这种模式,例如,将字符串数据转字节数据保存到文件中。或者将字节数据转流数据等。比如 InputStreamReader,OutputStreamWriter
- InputStreamReader 与 OutputStreamWriter 分别基础Reader 和 Writer,并且构造方法中都需要给一个InputStream 和 OutputStream实例。这里面 InputStreamReader 与 OutputStreamWriter 的作用就是将 InputStream 和 OutputStream适配到 Reader 和 Writer
- InputStreamReader 实现了Reader接口,并且持有InputStream的引用,通过StreamDecoder间接引用的。因为从byte到Char需要编码
- 很显然适配器就是InputStreamReader,目标接口是Reader,源接口/类 就是InputStream,我们利用InputStream的实现来实现这个Reader接口。
- OutputStreamWriter类也是一样的结构
- I/O类库中还有其他类似案例:StringReader将 String类适配到Reader接口,ByteArrayInputStream 适配器将byte数组适配到InputStream流处理接口。
设计模式解析–装饰器模式
- 装饰器,就是讲某个类重新装扮一下,使得它功能更强,当作为原来这个类的使用者还不应该收到装饰器前后装饰的影响,不破坏原有类结构,所以装饰器对是对被装饰类使用者透明。
装饰器模式的结构
- 装饰器UML模式如下
-
Component:抽象组件角色,定义一组抽象接口,规定这个被装饰组件的功能
-
ConcreteComponent:实现这个抽象组件的所有功能
-
Decorator:装饰器角色,持有一个Comonent对象实例的引用,定义一个与抽象组件一致的接口。
-
ConcreteDecorator:具体装饰器实践者,负责实现装饰器角色定义的功能
-
如下简单案例
//初始功能接口定义
public interface FlyConponent {void flay();
}
//初始功能实现
public class FlyConcreteComponent implements FlyConponent {@Overridepublic void flay() {System.out.println("to fly");}
}
//装饰器角色
public class FlyDecorator implements FlyConponent {public FlyConponent flyConponent;public FlyDecorator(FlyConponent flyConponent) {this.flyConponent = flyConponent;}@Overridepublic void flay() {flyConponent.flay();}
}//装饰器实现
public class EagleFlyComponent extends FlyDecorator {private String tool;public EagleFlyComponent(FlyConponent flyConponent, String tool) {super(flyConponent);this.tool = tool;}public void birdFlay() {System.out.print(" use " + tool);flyConponent.flay();}
}
- EagleFlyComponent 通过FlyDecorator 获取到原始接口功能的引用,让后利用最初始的实现FlyConcreteComponent 来实现自己新的功能 birdFlay
java I/O中的装饰器模式
-
上面案例中,装饰器模式就是赋予被装饰类更多的功能,在Java I/O中,有很多组合功能情况,这些不同功能的组合就是装饰器实现的,比如FilterInputStream为案例说明
-
如下FilterInputStream的UML图
-
InputStream类是一个抽象类,FileInputStream是具体的组件,实现了抽象类所有接口,所以FilterInputStream是我们的装饰角色,他实现了InputStream所有接口,并且持有InputStream的一个实例
-
BufferInputStream是具体的装饰器实现,他给InputStream增加了功能。这个装饰器类作用就是使InputStream读取数据保存在内存中。从而提高读取的性能
-
与只类似的功能的还有LineNumberINputStream,作用是按行读取数据的功能,他们使InputStream类增强了功能,或者提升性能。
适配器模式与装饰器模式区别
- 装饰器,与适配器都属于包装(Wrapper)模式。都是起到了包装一个类或者接口的作用,但是目的不一样
- 适配器模式是要将一个接口转成另外一个接口,他的目的是通过改变接口来达到重复使用的目的
- 装饰器不是要改变被装饰对象的接口,而是保持原有接口,但是增强原有对象的功能或者改变原有对象的处理方法从而提升性能。
- 因此两个模式的设计目的是不同的。