适配器模式(Adapter Pattern)
序言
在软件开发的世界中,我们经常会遇到一个棘手的问题:随着系统的发展与迭代,新功能的需求不断涌现,而这些新功能往往需要与旧有系统进行交互。这就带来了一个挑战——新旧系统之间由 于接口不兼容、数据格式不同或是通信协议有所差异等问题,导致无法直接协同工作。如何让这些原本因接口或功能不匹配的组件能够无缝对接,共同完成任务?
面对这一问题,适配器模式(Adapter Pattern)应运而生。适配器模式是一种结构型设计模式,它通过引入一个中间层——即“适配器”——来解决两个不兼容接口之间的矛盾。这个适配器充当转换器的角色,将一种接口转换成另一种客户端期望的接口,从而实现了原有功能的新用途。
就像电源插头与插座的关系一样,虽然电源插头的形状各异,但只要使用对应的转换器,就可以在不同标准的电源插座中供电。在软件设计中,适配器模式允许已有的类或模块通过引入适配器来复用,而无需修改原有代码,大大增强了系统的灵活性和可扩展性。
定义
Convert the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
结构
想象这样一个场景,在微服务场景下,有一个接口升级,参数发生了变更。但是有其他服务在大量使用老版接口,为了不影响原有业务,需要确保老版接口依然可以正常使用。那这时候就需要一个适配层,接受老版参数,然后转为新版参数,再调用新版的业务接口处 理相关的业务逻辑。
实现
@Data
public class ParamV2 {
private String name;
private String code;
private Integer type;
}
public interface ServiceV2 {
void doService(ParamV2 param);
}
public class ServiceV2Impl implements ServiceV2 {
@Override
public void doService(ParamV2 param) {
System.out.println("升级后的业务处理逻辑");
}
}
V1版本接口适配V2版本接口
@Data
public class ParamV1 {
private String name;
private String code;
}
public interface ServiceV1 {
void doService(ParamV1 param);
}
public class ServiceV2Adapter implements ServiceV1 {
private final ServiceV2 serviceV2;
public ServiceV2Adapter(ServiceV2 serviceV2) {
this.serviceV2 = serviceV2;
}
@Override
public void doService(ParamV1 param) {
ParamV2 paramV2 = new ParamV2();
paramV2.setName(param.getName());
paramV2.setCode(param.getCode());
// 设置一个默认值
paramV2.setType(1);
System.out.println("旧版本业务类做参数转换");
this.serviceV2.doService(paramV2);
}
}
测试
public class Main {
public static void main(String[] args) {
ServiceV2 serviceV2 = new ServiceV2Impl();
ServiceV1 serviceV1 = new ServiceV2Adapter(serviceV2);
ParamV1 paramV1 = new ParamV1();
paramV1.setName("张三");
paramV1.setCode("zhangsan");
serviceV1.doService(paramV1);
}
}
输出
旧版本业务类做参数转换
升级后的业务处理逻辑
通过适配层,旧版本接口无需任何改动就可以适配新版本接口。这样可以减少大量的接口升级对业务系统的改动。
本例中仅是做参数的适配,也可以做业务接口适配,即抛开
ServiceV2
,ServiceV2
是一套新的业务逻辑。而在ServiceV2Adapter
直接调用其他业务接口实现新版业务逻辑,而不必拘泥一定要转换为ServiceV2
的参数,来调用ServiceV2
的业务接口。
适配层的主要作用是做适配,只要完成了适配任务,我认为都是没有问题的。