Java 设计模式 - 适配器模式
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式是 Adapter,也称 Wrapper (所以如果看到源码中有以这两个结尾的类,那么大概率使用了适配器模式),java 中实现适配器模式共有三种:
- 类适配器: 当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可
- 对象适配器: 当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个 Wrapper 类,持有原类的一个实例,在 Wrapper 类的方法中,调用实例的方法就行。使用组合替代继承,故相比较类适配器,对象适配器更加常用。
- 接口适配器: 当不希望实现一个接口中所有的方法时,可以创建一个抽象类 Wrapper,实现所有方法,我们写别的类的时候,继承抽象类即可
适配器是为了解决类兼容性问题的,实际上 java 标准库中也有很多地方使用了适配器模式,典型的线程池中为了能让 Thread 可以调用 Callable 接口使用了 RunnableAdapter 这个类:
private static final class RunnableAdapter<T> implements Callable<T> {
private final Runnable task;
private final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
public String toString() {
return super.toString() + "[Wrapped task = " + task + "]";
}
}
实现
我们以给手机充电来举例说明适配器的用途
定义 220V 的电源
/**
* 中国的电源-220V
*/
public class PowerWith220V {
public Integer discharge() {
System.out.println("220V 的电源正在放电...");
return 220;
}
}
定义充电器
/**
* 充电器
*/
public interface Charger {
/**
* 接入电源
* @param powerWith220V
* @return
*/
Boolean connectPower(PowerWith220V powerWith220V);
}
/**
* 实际充电器
*/
public class ChargerImpl implements Charger {
private PowerWith220V powerWith220V;
@Override
public Boolean connectPower(PowerWith220V powerWith220V) {
this.powerWith220V = powerWith220V;
System.out.println("充电器接入电源成功");
return Boolean.TRUE;
}
}
定义手机
/**
* 手机
*/
public class Phone {
private String name;
public Phone(String name) {
this.name = name;
}
public void charge(Charger charger) {
charger.discharge(36);
System.out.println(name + "正在充电... ");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
模拟下手机充电
public class Test {
public static void main(String[] args) {
//定义一个手机
Phone phone = new Phone("vivo");
//定义一个 220v 电源
PowerWith220V powerWith220V = new PowerWith220V();
//定义一个充电器
Charger charger = new ChargerImpl();
//充电器接入电源
charger.connectPower(powerWith220V);
//手机充电
phone.charge(charger);
}
}
以上没有问题,但突然某一天手机的使用者来到了美国,而美国的电源都是 110V 的,如果是以上设计,明显就无法满足需求了
所以为了能成功给手机充电,我们就需要一个适配器:
先定义一个 110V 的电源
public class PowerWith110V {
public Integer discharge() {
System.out.println("110V 的电源正在放电...");
return 110;
}
}
定义适配器
/**
* 新充电器
*/
public interface NewCharger extends Charger {
/**
* 接入电源
* @param powerWith110V
* @return
*/
Boolean connectPower(PowerWith110V powerWith110V);
}
/**
* 充电适配器
*/
public class ChargerAdapter implements NewCharger {
private Charger charger;
private PowerWith110V powerWith110V;
public ChargerAdapter(Charger charger) {
this.charger = charger;
}
@Override
public Boolean connectPower(PowerWith110V powerWith110V) {
this.powerWith110V = powerWith110V;
System.out.println("充电器接入 110V 电源成功");
return Boolean.TRUE;
}
@Override
public Boolean connectPower(PowerWith220V powerWith220V) {
return charger.connectPower(powerWith220V);
}
}
继续充电
public class Test {
public static void main(String[] args) {
//定义一个手机
Phone phone = new Phone("vivo");
//定义一个 220v 电源
PowerWith220V powerWith220V = new PowerWith220V();
//定义一个充电器
Charger charger = new ChargerImpl();
//接入 220V 电源
charger.connectPower(powerWith220V);
//手机充电
phone.charge(charger);
//定义一个 110V 的电源
PowerWith110V powerWith110V = new PowerWith110V();
//定义适配器
NewCharger newCharger = new ChargerAdapter(charger);
//接入 110V 电源
newCharger.connectPower(powerWith110V);
//手机充电
phone.charge(newCharger);
//同样可以接入 220V 电源
newCharger.connectPower(powerWith220V);
phone.charge(newCharger);
}
}
其实这个示例中可以理解为:
- 为了能将电源的电提供给手机,使用了适配器-创建一个充电器(转换电源)
- 为了能兼容 220V 和 110V 的电源,使用了适配器-创建了一个充电适配器(转换不同电源)
市面上常用的各种转接头如果用代码实现的话,也可以认为是适配器模式。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Java 设计模式 - 装饰器模式
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论