适配器模式是指把一个类的接口转换成另一个接口,使得原本不相兼容的类可以一起工作,属于结构型设计模式。可以说,适配器模式主要是解决功能兼容性问题。
我们都知道:在日常生活中,我们的电源插座都是220V的交流电,因此给手机充电都需要一个电源适配器进行转换,这个手机的电源适配器(也就是充电器)就是一个起着转换作用的角色。
我们用代码来模拟一下这个场景。
1,创建220V交流电(原始功能)
创建220V交流电类如下:
package fun.swsk33site.adapter.model;
/**
* 220V交流电
*/
public class AC220V {
/**
* 接入交流电并获取
*
* @return 获取到220V交流电
*/
public int output() {
return 220;
}
}
复制代码
这个类就可以得到220V的电流了!但是这个无法直接使用,因此需要做转换。
2,创建适配器接口,并实现各个适配器(适配器,用于转换原始功能)
电源适配器并非只有一种,比如华为40W快充和苹果的充电器就不一样,因此我们要把适配器先抽象为一个接口,再去实现各个适配器:
package fun.swsk33site.adapter.adapter;
/**
* 电源适配器接口
*/
public interface PowerAdapter {
/**
* 对输入电源作转换
*
* @return 转换后电流
*/
int doConvert();
}
复制代码
实现华为40W快充适配器:
package fun.swsk33site.adapter.adapter.impl;
import fun.swsk33site.adapter.adapter.PowerAdapter;
import fun.swsk33site.adapter.model.AC220V;
/**
* 华为40W快充适配器
*/
public class HuaweiFastCharge implements PowerAdapter {
private AC220V ac220V;
/**
* 构造器依赖注入(模拟华为充电器接入220V交流电)
*
* @param ac220V 接入的交流电
*/
public HuaweiFastCharge(AC220V ac220V) {
this.ac220V = ac220V;
}
@Override
public int doConvert() {
// 转换为10V电流
int output = ac220V.output() / 22;
return output;
}
}
复制代码
实现苹果5W手机充电器:
package fun.swsk33site.adapter.adapter.impl;
import fun.swsk33site.adapter.adapter.PowerAdapter;
import fun.swsk33site.adapter.model.AC220V;
/**
* 苹果5V手机充电器
*/
public class AppleCharge implements PowerAdapter {
private AC220V ac220V;
/**
* 构造器依赖注入(模拟苹果充电器接入220V电源)
*
* @param ac220V
*/
public AppleCharge(AC220V ac220V) {
this.ac220V = ac220V;
}
@Override
public int doConvert() {
int output = ac220V.output() / 44;
return output;
}
}
复制代码
可见,不同的适配器都对原始的功能进行了转换,只不过转换的方式不一样。
3,使用适配器
我们在主方法中试一下子:
PowerAdapter huaweiAdapter = new HuaweiFastCharge(new AC220V());
System.out.println("华为充电器,得到电压:" + huaweiAdapter.doConvert());
PowerAdapter appleAdapter = new AppleCharge(new AC220V());
System.out.println("苹果充电器,得到电压:" + appleAdapter.doConvert());
复制代码
结果:
4,总结
可见适配器模式主要是做了一个转换和兼容的工作。适配器中输入的是原始功能(220V交流电),而输出的是转换后兼容的功能(10V或者5V直流电),至于转换的逻辑,当然就是放在适配器类中了!其实还是很简单的。
通常适用于以下场景:
- 已经存在的类和需求不匹配
- 软件系统升级之后,不同的功能导致了不兼容问题
事实上,我们很多网站都有登录功能,除了可以密码登录之外,还可以QQ或者微信登录。这么多登录方式是如何组织起来的呢?其实使用适配器模式+策略模式即可完成。这样登录形式丰富了,但是后台的处理逻辑几乎不用怎么变,符合开闭原则。
上述示例的类图如下: