# 适配器模式Adapter
阅读量 loading
# 一、概念
# 1、定义
将一个类的接口(被适配者)转换成客户期望的另一个结构(目标类),使原本不兼容的类可以一起工作
# 2、类型
结构型
# 3、适用场景
- 已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
- 不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案
# 4、优点
- 能提高类的透明性和复用,现有的类复用但不需要改变
- 目标类和适配器类解耦,提高程序扩展性
- 符合开闭原则
# 5、缺点
- 适配器编写过程需要全面考虑,可能会增加系统的复杂性
- 增加系统代码可读的难度
# 6、扩展
# 类适配器
通过类继承实现的
# 对象适配器
符合组合复用原则,并且使用委托机制,通过组合实现
# 7、相关设计模式
- 适配器模式和外观模式
都是对现有的类进行封装。适配器模式复用原有的接口,使两个已有的接口协同工作;而外观模式定义了新的接口,在现有的系统中提供一个更方便的访问入口。
# 二、Coding
先介绍一下适配器模式中被适配者的角色:
public class Adaptee {
public void adapteeRequest() {
System.out.println("被适配者的方法");
}
}
1
2
3
4
5
6
2
3
4
5
6
目标类,也就是适配后,最终我们想要的类:
public interface Target {
void request();
}
1
2
3
4
2
3
4
这里定义为了一个接口。
目标类的具体实现类:
public class ConcreteTarget implements Target {
@Override
public void request() {
System.out.println("ConcreteTarget目标方法");
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
接下来就是最终要的适配器类了。
# 类适配器
类适配器中的适配器类是通过继承被适配类实现的:
public class Adapter extends Adaptee implements Target {
@Override
public void request() {
super.adapteeRequest();
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
通过继承被适配者,然后实现目标接口,在目标接口的方法中调用了被适配者的方法,这样就将被适配者的方法适配到了目标方法。实际上在调用父类的的 adapteeRequest()
方法前后还可以做一系列操作来实现代码增强。
应用层:
public static void main(String[] args) {
Target target = new ConcreteTarget();
target.request();
Target adapterTarget = new Adapter();
adapterTarget.request();
}
1
2
3
4
5
6
7
2
3
4
5
6
7
target
是原始的 Target
的实现类,后面通过适配器实现了 Target
接口,实际在适配器内部调用的是被适配者的方法,从而完成了适配。
运行结果:
ConcreteTarget目标方法
被适配者的方法
1
2
2
# 对象适配器
对象适配器的适配器类是通过组合被适配器实现的:
public class Adapter implements Target {
private Adaptee adaptee = new Adaptee();
@Override
public void request() {
adaptee.adapteeRequest();
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
也同样完成了适配功能。同样的在适配过程前后可以增加自己的逻辑代码。
应用层不用变化,直接可以复用:
public static void main(String[] args) {
Target target = new ConcreteTarget();
target.request();
Target adapterTarget = new Adapter();
adapterTarget.request();
}
1
2
3
4
5
6
7
2
3
4
5
6
7
运行结果:
ConcreteTarget目标方法
被适配者的方法
1
2
2
一样的效果。
# 应用
最能体现适配器模式的就是充电器的适配电源了,将220V交流电(被适配者)通过手机充电器(适配器)转换为手机充电电压(目标)。先看下被适配者类,也就是220V交流电:
public class AC220 {
public int outputAC220V() {
int output = 220;
System.out.println("输出交流电" + output + "V");
return output;
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
接下来是目标类,5v直流电:
public interface DC5 {
int outputDC5V();
}
1
2
3
4
2
3
4
最终要的角色,手机充电器,也就是适配器:
public class PowerAdapter implements DC5 {
private AC220 ac220 = new AC220();
@Override
public int outputDC5V() {
int adapterInput = ac220.outputAC220V();
// 变压器
int adapterOutput = adapterInput / 44;
System.out.println("使用PowerAdapter输入AC:" + adapterInput + "V,输出DC:" + adapterOutput);
return adapterOutput;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
这里通过组合的方式,在 outputDC5V()
方法中调用了被适配者的 outputAC220V()
方法,并做了逻辑处理,完成了适配。
看下应用层:
public static void main(String[] args) {
DC5 dc5 = new PowerAdapter();
dc5.outputDC5V();
}
1
2
3
4
2
3
4
运行结果:
输出交流电220V
使用PowerAdapter输入AC:220V,输出DC:5
1
2
2
是不是很简单。