文章目录
1. 插座问题
泰国的插座是两口的, 中国是三口的, 去泰国怎么使用充电器?
买个多功能转换插头(适配器) 就OK了
2. 基本介绍
- 适配器模式是将某个类的接口转换成客户端所期望的另一个接口表示, 主要目的是兼容性, 让原本因为接口不匹配不能在一起工作的两个类可以协同工作. 其别名为包装器 (Wrapper)
- 适配器,模式属于结构型模式
- 主要分成三类: 类适配器模式 对象适配器模式 接口适配器模式
3. 工作原理
- 适配器模式: 将一个类接口转换成另一个接口, 让原本接口不兼容的类可以兼容
- 从用户的角度看不到被适配者, 是解耦的
- 用户调用适配器转化出来的目标接口方法, 适配器再调用被适配者的相关接口方法
- 用户收到反馈结果, 感觉只是和目标接口交互, 如图
4. 类适配器模式
4.1 基本介绍
Adapter类, 通过集成src类, 实现dst类接口, 完成src -> dst的适配
4.2 案例
以生活中充电器的例子来讲解适配器,充电器本身相当于Adapter,220V交流电
相当于src (即被适配者),我们的目dst(即 目标)是5V直流电
package com.liyang;
// 1. 源电压220V
public class Voltage220V {
public int outputVoltage() {
return 220;
}
}
package com.liyang;
// 2. 手机类, 只能使用5V的电压
public class Phone {
public void charging(Voltage5V voltage5v) {
if (voltage5v.outputVoltage() == 5) {
System.out.println("正在以5V充电呢...");
} else {
System.out.println("电压不对, 无法充电...");
}
}
}
package com.liyang;
// 3. 那么我们在这里做一个适配器接口, 对220V的电压进行时适配
public interface Voltage5V {
public int outputVoltage();
}
package com.liyang;
public class VoltageAdapter extends Voltage220V implements Voltage5V {
@Override
public int outputVoltage() {
return super.outputVoltage()/44;
}
}
package com.liyang;
// 4. 使用下
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
4.3 注意事项
- java的单继承机制, 所以类适配器需要继承src类算是一个缺点, 因为这就要求dst必须是接口, 有一定的局限性
- src类的方法在Adapter中都会暴露出来, 也增加了使用成本
- 由于其继承了src类, 所以可以根据需求重写src类的方法, 使得Adapter的灵活性增强
5. 对象适配器
5.1 介绍
- 基本思路相同, 只是Adapter类不继承Src类, 而是持有src的实例, 以解决兼容性问题
- 根据 合成复用原则 , 尽量使用关联来替代继承
- 对象是配偶器是最常用的
5.2 案例
package com.liyang;
// 1. 源电压220V
public class Voltage220V {
public int outputVoltage() {
return 220;
}
}
package com.liyang;
// 2. 手机类, 只能使用5V的电压
public class Phone {
public void charging(Voltage5V voltage5v) {
if (voltage5v.outputVoltage() == 5) {
System.out.println("正在以5V充电呢...");
} else {
System.out.println("电压不对, 无法充电...");
}
}
}
package com.liyang;
// 3. 那么我们在这里做一个适配器接口, 对220V的电压进行时适配
public interface Voltage5V {
public int outputVoltage();
}
package com.liyang;
public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220v;
public void setVoltage220v(Voltage220V voltage220v) {
this.voltage220v = voltage220v;
}
@Override
public int outputVoltage() {
return voltage220v.outputVoltage()/44;
}
}
package com.liyang;
// 4. 使用下
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
VoltageAdapter voltageAdapter = new VoltageAdapter();
voltageAdapter.setVoltage220v(new Voltage220V());
phone.charging(voltageAdapter);
}
}
5.3 注意事项
- 使用组合代替继承, 解决了类适配器必须继承src的局限性问题, 也不再要求dst必须是接口
- 成本更低 更灵活
6. 接口适配器
6.1 介绍
- 当不需要全部实现接口的方法, 可以先设计一个抽象类实现接口, 提供默认实现(空方法), 这样该抽象类的子类就可以有选择的重写某些方法
- 使用于一个接口不想使用其所有方法的情况
- 又叫适配器模式 或者 缺省适配器模式