1. 定义
适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
类似电源适配器、转接口、转换器等,解决两者接口不匹配或结构不兼容的问题。
2. 设计
主要角色:
- 目标类(Target),定义客户需要的接口。可以是抽象类或者接口,或者具体类。
- 被适配类(Adaptee),定义需要适配的接口。一般为具体类。
- 适配器类(Adapter),继承目标,引用被适配类,对目标和被适配类进行适配。也可以都采用继承的方式。
类图如下:
适配器模式-类图具体有这几种实现:
- 继承方式,类适配器。
- 组合方式,对象适配器。
- 接口的默认空实现,接口适配器。
2.1. 类适配器
通过 继承 来实现适配功能。
目标接口,定义要转换后的接口。
public interface Target {
void request();
}
适配者类,定义要被转换的接口。
public class Adaptee {
public void adapteeRequest() {
System.out.println("adaptee Request");
}
}
适配器,像变魔术一样接口转换。
public class Adapter extends Adaptee implements Target {
public void request() {
adapteeRequest();
}
}
客户端使用对比:
public class TestAdapter {
public static void main(String[] args) {
// 适配前的接口
Adaptee adaptee = new Adaptee();
adaptee.adapteeRequest();
// 适配后的接口
Target target = new Adapter();
target.request();
}
}
2.2. 对象适配器
通过 组合 来实现适配功能。
把上面的 Adapter 改造一下,不再使用继承,而是让 Adaptee 作为成员变量:
public class Adapter implements Target {
public Adaptee adaptee = new Adaptee();
public void request() {
adaptee.adapteeRequest();
}
}
2.3. 接口适配器
接口模式的适配器,其实是对需要实现方法很多的接口提供一个默认的空实现。
如果使用的方法很多,但应用的时候只需要部分方法的情况下,可以只实现部分方法。
比如有个监听器定义了一堆方法:
public interface Listener {
void sayYes();
void sayNo();
void sayHello();
void sayGoodBye();
void sayHappy();
void saySad();
void sayHi();
}
客户使用的时候,只关心 sayHello 的监听。
创建一个 Listener 的 Adapter:
public class ListenerAdapter implements Listener {
public void sayYes() {
}
public void sayNo() {
}
public void sayHello() {
}
public void sayGoodBye() {
}
public void sayHappy() {
}
public void saySad() {
}
public void sayHi() {
}
}
然后使用的时候,就可以只实现调用者关心的回调函数了。
public class TestAdapter {
public static void main(String[] args) {
Listener listener = new ListenerAdapter() {
@Override
public void sayHello() {
System.out.println("hello.");
}
};
listener.sayHello();
}
}
3. 应用
应用场景:
- 要使用一些系统原有的类,但接口不满足当前设计。
- 要创建一个可重复使用的类,相对独立,和其他类没有太大关联,同时未来还会继续扩展和修改。
3.1. JDK:Executors 的 RunnableAdapter
3.2. JDK:InputStreamReader 和 OutputStreamWriter
4. 特点
4.1. 优势
- 解耦。目标类与适配者解耦。两者独立发展,互不影响。
- 易复用。一个适配者可以多个不同的系统中复用。
- 易扩展。可以不修改原本代码的情况下增加适配者,也可以通过配置文件指定。符合开闭原则。
4.2 缺点
- 类适配
- 不支持多重继承的语言,不能同时适配多个适配者
- 适配者不能成为最终类。
- 对象适配,置换适配者比较复杂。
网友评论