结构型 - 适配器(Adapter)
Chivas-Regal
# 概述
适配器可以将一个类的接口转化为客户端所期望的另一种接口,使得原本因接口不兼容导致不能一起工作的类可以协同工作。
# 实现
有两种实现方式
- 类适配器(通过继承实现)
- 对象适配器(通过组合实现)
凭借组合优于继承的条件,对象适配器往往更加灵活。
# 对象适配器(组合)
场景:电压转换器
假如我们有个 220V 电压的电源,但是给手机充电只需要 5V 的电压。
public interface VoltageV5 {
int getV5();
}
1
2
3
2
3
public class VoltageV220 {
public int getV220() {
return 220;
}
}
1
2
3
4
5
2
3
4
5
public class VoltageV220ToV5Adapter implements VoltageV5 {
private VoltageV220 v220;
public VoltageV220ToV5Adapter(VoltageV220 v220) {
this.v220 = v220;
}
@Override
public int getV5() {
return v220.getV220() / 44;
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
客户端则是可以统一使用 5V 接口完成多态调用。
public class Phone {
public void charging (VoltageV5 v5) {
if (v5.getV5() == 5) {
log.info("电压正常,开始充电...");
...
} else {
log.info("电压异常,即将爆炸!!!");
}
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
public class Test {
public static void main (String[] args) {
VoltageV5 v5 = new VoltageV220ToV5Adapter();
Phone phone = new Phone();
phone.charging(v5);
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 类适配器(继承)
此处直接展示 VoltageV220ToV5Adapter 的写法
public class VoltageV220ToV5Adapter extends VoltageV220 implements VoltageV5 {
@Override
public int getV5() {
return getV220() / 44;
}
}
1
2
3
4
5
6
2
3
4
5
6
# 实际应用-日志框架兼容
这是一个老生常谈的问题了,项目中存在多个第三方日志工具,需要把它们统一起来,但是各个日志工具打印日志方法名又不同。
public interface Logger {
void log(String msg);
}
1
2
3
2
3
// 第三方日志
public class LoggerA {
public void logMessage (String msg) {
System.out.println("[LoggerA]" + msg);
}
}
// 适配器
public class Adapter4LoggerA implements Logger {
private LoggerA loggerA;
public Adapter4LoggerA(LoggerA loggerA) {
this.loggerA = loggerA;
}
@Override
public void log(String msg) {
loggerA.logMessage(msg);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 第三方日志
public class LoggerB {
public void showIt (String msg) {
System.out.println("[LoggerB]" + msg);
}
}
// 适配器
public class Adapter4LoggerB implements Logger {
private LoggerB loggerB;
public Adapter4LoggerB(LoggerB loggerB) {
this.loggerB = loggerB;
}
@Override
public void log(String msg) {
loggerB.showIt(msg);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18