定义:
将类的接口转换为客户期望的另一个接口,适配器可以让不兼容的两个类一起协同工作
适配器模式的关键点就在于转换,而转换时要在已有的接口基础上做好兼容
核心原理:
在原有的接口或类的外层封装一个新的适配器层,以实现扩展对象结构的效果,并且这种扩展可以无限扩展下去
使用场景:
- 原有接口无法修改时
- 原有接口功能太老旧时
- 统一多个类的接口设计时
- 需要过渡升级旧接口时
- 需要依赖外部系统时
- 适配不同数据格式时
- 不同接口协议转换时
第一类就是原有接口功能不满足现有要求,需要在兼容老接口的同时做适当的扩展;
第二类是有相似性的多个不同接口之间做功能的统一
UML图
适配器模式中包含三个关键角色:
- 目标类, 适配器类即将要进行适配的抽象类或接口
- 适配器类, 可以是类或接口,是作为具体适配者类的中间类来使用
- 具体适配者类, 可以是内部的类或服务,也可以是外部对象或服务
模式代码示例
/**
* @Description 目标类
*/
public interface Service {
String filter(String str);
}
import lombok.NoArgsConstructor;
/**
* @Description 目标实现类
*/
@NoArgsConstructor
public class ServiceImpl implements Service {
@Override
public String filter(String str) {
return str.replaceAll("a","A");
}
}
/**
* @Description 适配器类
*/
public class Adapter implements Service{
private OtherClass otherClass;
private TargetAbstractionImpl impl;
public Adapter(OtherClass otherClass, TargetAbstractionImpl impl){
this.otherClass = otherClass;
this.impl = impl;
}
/**
* filter保留了原来的功能
*
* @param str
* @return
*/
@Override
public String filter(String str) {
otherClass.preCheck(str); // 在filter中加入了新功能 preCheck
return impl.filter(str);
}
}
import lombok.NoArgsConstructor;
/**
* @Description 适配者类
*/
@NoArgsConstructor
public class OtherClass {
public String replace(String str){
return str.replaceAll("<","[");
}
public void preCheck(String str){
System.out.println("PreCheck: " + str);
}
}
Adapter 类充当了一个中间者的角色,Adapter 类实现目标类TargetAbstraction 并实现接口 filter
同时在 fliter 中加入新的扩展功能,扩展功能使用具体适配者类 OtherClass 来实现,这样在保留原有 filter 功能的同时,也增加了新的功能
代码示例
示例1 类适配器模式
public interface IVoltage5V {
int output5V();
}
/**
* @Description 需要适配的类
*/
public class Voltage220V {
public int output220V() {
System.out.println("输出220V电压");
return 220;
}
}
/**
* @Description 适配器
*/
public class VoltageAdapter extends Voltage220V implements IVoltage5V{
@Override
public int output5V() {
int src = output220V();
int dst = src / 44;
return dst;
}
}
/**
* @Description 使用者
*/
public class Phone {
/**
* 传入 目标接口
* @param iVoltage5V
*/
public void charging(IVoltage5V iVoltage5V) {
if (iVoltage5V.output5V() == 5) {
System.out.println("5V可以充电");
} else if (iVoltage5V.output5V() > 5) {
System.out.println("大于5V不可以充电");
}
}
}
/**
* @Description 测试用例
*/
public class Client {
public static void main(String[] args) {
System.out.println("======= 类适配器模式 =======");
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
示例2 接口适配器模式
public interface Inteface4 {
void m1();
void m2();
void m3();
void m4();
}
public class AbsAdapter implements Inteface4 {
@Override
public void m1() {
System.out.println("m1方法");
}
@Override
public void m2() {
}
@Override
public void m3() {
}
@Override
public void m4() {
}
}
public class Client {
public static void main(String[] args) {
// 只需实现 用到的方法
AbsAdapter absAdapter = new AbsAdapter() {
@Override
public void m1() {
super.m1();
}
};
absAdapter.m1();
}
}
示例3 对象适配器模式
/**
* @Description 适配接口
*/
public interface IVoltage5V {
int output5V();
}
/**
* @Description 需要适配的类
*/
public class Voltage220V {
/** src
*
* @return
*/
public int output220V() {
System.out.println("输出220V电压");
return 220;
}
}
/**
* @Description 适配器类
*/
public class VoltageAdapter implements IVoltage5V {
private Voltage220V voltage220V;
public VoltageAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
/**
* 适配器
* @return
*/
@Override
public int output5V() {
int dst = 0;
if (null != voltage220V) {
int src = voltage220V.output220V();
dst = src / 44;
}
return dst;
}
}
public class Phone {
/**
* 传入 目标接口
* @param iVoltage5V
*/
public void charging(IVoltage5V iVoltage5V) {
if (iVoltage5V.output5V() == 5) {
System.out.println("5V可以充电");
} else if (iVoltage5V.output5V() > 5) {
System.out.println("大于5V不可以充电");
}
}
}
public class Client {
public static void main(String[] args) {
System.out.println("======= 对象适配器模式 =======");
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage220V()));
}
}