结构型模式
核心作用
- 是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题。
分类
- 适配器模式、代理模式、桥接模式、装饰模式、组合模式、外观模式、享元模式
适配器模式(Adapter)
生活中的适配器:USB数据转接口、三孔转两孔插座等。
什么是适配器模式
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
模式中的角色
- 目标接口(Target):客户所期待的接口。目标可以是具体的或者抽象的类,也可以是接口。
- 需要适配的类(Adaptee):需要适配的类或适配者类。
- 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
适配器模式示例
现有一个笔记本电脑,只具有USB接口,有一个键盘ps/2接口,现笔记本电脑要使用此键盘,那么就需要一个USB与ps/2之间的转换器。
方式一:类适配
客户端:Client.java
/**
* User:tumbler
* Desc:适配器模式--客户端
* 笔记本电脑:只有USB接口
*/
public class Client {
public void test1(Target target) {
target.handleRequest();
}
}
可见客户端想要的目标是Target类型的参数,并且需要一个处理请求的方法handleRequest()完成键盘打字功能。
所以我们建一个目标接口Target.java,并提供此方法:
/**
* User:tumbler
* Desc:适配器模式--客户需要目标接口
*/
public interface Target {
void handleRequest();
}
被适配者键盘,它可以打字:Adaptee.java
/**
* User:tumbler
* Desc:适配器模式--被适配的类
* 相当于 ps/2键盘
*/
public class Adaptee {
public void request() {
System.out.println("可完成客户需要的功能...打字");
}
}
在目标接口和键盘之间建立一个适配器Adapter.java,使之能正常工作:
/**
* User:tumbler
* Desc:适配者模式 --- 适配器 (类适配器)
* 相当于USB和ps/2的转接器
*/
public class Adapter extends Adaptee implements Target {
@Override
public void handleRequest() {
super.request();
}
}
这里直接继承被适配者,使适配器直接拥有适配者的功能,称之为类适配,然而这样做并不灵活,因为java只能单继承。
此时UML图如下,可以看出客户端只用关心他需要的目标类,不关心具体完成功能的其他操作:
方式二:对象适配
创建适配器类Adapter2.java
/**
* User:tumbler
* Desc:适配器模式--对象适配器(使用组合的方式)
*/
public class Adapter2 implements Target{
private Adaptee adaptee;
public Adapter2(Adaptee adaptee){
this.adaptee = adaptee;
}
@Override
public void handleRequest() {
adaptee.request();
}
}
客户端还是不变,UML图如下:
从中都可以看出,客户端只需要它想要的目标类,而目标类和被适配者之间由适配器关联,从而达到完成客户端的请求。
工作中的使用场景
- 经常用来做旧系统的改造和升级。
- 如果我们的系统开发之后再也不需要维护,那么许多模式都是不需要的,但不幸的是,维护一个系统的代价往往是开发一个系统的数倍。
常见应用
- java.io.InputStreamReader(InputStream)
- java.io.OutputStreamWriter(OutputStream)