类别:结构型设计模式
目的:将历史遗留代码(通常是一个library)/三方代码转换成一个新接口,使得可以在使用这个新接口的项目中使用
完整代码参考:https://1drv.ms/u/s!AquRvPzqx59Ri3_qC9egk9qojRQp?e=oiO1Jh
典型场景
这里拿一个系统中的支付模块举例,一个支付模块会对接多个支付比如微信,支付宝等
基本事实
在现有代码中,已在使用一种支付方式处理订单,对应的支付接口Pay.java参考如下
public interface Pay {
void setAmount(Integer amount);
void makePayment();
}
上面这个接口的实现PayImpl.java
public class PayImpl implements Pay {
@Override
public void setAmount(Integer amount) {
System.out.println("set pay impl");
}
@Override
public void makePayment() {
System.out.println("make payment");
}
}
serviceMyService.java
中使用支付方式处理订单,参考如下:
public class MyService {
public void processOrder(Pay pay) {
pay.setAmount(1);
pay.makePayment();
}
}
调用参考
var myservice = new MyService();
var pay = new PayImpl();
myservice.processOrder(pay);
运行效果如下:
可以看到现有支付调用是ok的
接入一个新的支付方式
新的支付方式比如Pay1的接口Pay1.service
参考如下:
public interface Pay1 {
void init();
void setPrice(Integer amount);
void processPay();
}
对应实现Pay1Impl.java
public class Pay1Impl implements Pay1 {
@Override
public void init() {
System.out.println("pay1 init");
}
@Override
public void setPrice(Integer amount) {
System.out.println("pay1 set amount");
}
@Override
public void processPay() {
System.out.println("pay1 make payment");
}
}
和现存支付接口对比
Pay1.java | Pay.java |
---|---|
init | 不存在 |
setPrice | setAmount |
processPay | makePayment |
可以看到被使用的第三方支付方式的接口和项目中现存的不一样,这样就不能在MyService中直接使用了(参考编辑器的提示)
这种情况就可以使用适配模式了
模式实现
就是将需要新增的三方支付方式Pay1适配成目前项目需要的Pay,新增一个类比如Pay1Adapter进行接口转换
Pay1Adapter.java参考如下:
public class Pay1Adapter implements Pay {
private Pay1 pay1;
public Pay1Adapter(Pay1 pay1) {
this.pay1 = pay1;
}
@Override
public void setAmount(Integer amount) {
pay1.init();
pay1.setPrice(amount);
}
@Override
public void makePayment() {
pay1.processPay();
}
}
适配效果如下
可以看到经过适配后,Pay1可以在需要Pay接口的项目中使用了
这个将Pay1接口转成Pay接口的Pay1Adapter就是适配器
UML
为什么要使用适配器
- 尽可能使用最少的代码复用三方代码
- 避免直接修改三方代码
一些注意的点
一般三方sdk不会为某个系统单独进行适配,就需要自行进行适配了