Appearance
适配器设计模式能使接口不兼容的对象能够相互合作,是作为两个不兼容的接口之间的桥梁,属于结构型模式
应用场景分析
假如你正在开发一款股票市场监测程序, 它会从不同来源下载 XML 格式的股票数据, 然后向用户呈现出美观的图表。在开发过程中, 你决定在程序中整合一个第三方智能分析函数库。 但是遇到了一个问题, 那就是分析函数库只兼容 JSON 格式的数据。
你无法 “直接” 使用分析函数库, 因为它所需的输入数据格式与你的程序不兼容。你可以修改程序库来支持 XML。 但是, 这可能需要修改部分依赖该程序库的现有代码。 甚至还有更糟糕的情况, 你可能根本没有程序库的源代码, 从而无法对其进行修改。
常见的几类适配器
- 类的适配器模式:想将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
- 对象的适配器模式:想将一个对象转换成满足另一个新接口的对象时,可以创建一个适配器类,持有原类的一个实例,在适配器类的方法中,调用实例的方法就行。
- 接口的适配器模式:不想实现一个接口中所有的方法时,可以创建一个Adapter,实现所有方法,在写别的类的时候,继承Adapter类即可。
接口的适配器模式
场景:不想实现一个接口中所有的方法时,可以创建一个Adapter,实现所有方法,在写别的类的时候,继承Adapter类即
新建一个支付网关
java
public interface PayGateway {
/**
* 下单
*/
void unifiedorder();
/**
* 退款
*/
void refund();
/**
* 查询支付状态
*/
void query();
/**
* 发红包
*/
void sendRedPack();
}
场景分析:现在我有一个类,想要实现PayGateway
中的两个方法,如果使用 implements
实现,其他的必须实现空方法,而空方法是没有意义的。
因此我们使用一个类来实现方法,后续的只需要继承即可适配器实现需要的方法即可。
==错误用法:==
java
public class ProductVideoOrder implements PayGateway{
@Override
public void unifiedorder() {
System.out.println("下单");
}
@Override
public void refund() {
System.out.println("退款");
}
@Override
public void query() {
}
@Override
public void sendRedPack() {
}
}
创建适配器
java
public class PayGatewayAdapter implements PayGateway{
@Override
public void unifiedorder() {
}
@Override
public void refund() {
}
@Override
public void query() {
}
@Override
public void sendRedPack() {
}
}
==正确用法==
java
public class ProductVideoOrder extends PayGatewayAdapter{
@Override
public void unifiedorder() {
System.out.println("下单");
}
@Override
public void refund() {
System.out.println("退款");
}
}
类的适配器模式
需求:有一个旧的类,功能稳定运行,如何在不修改旧的类的情况下新增功能?
应用场景
有个电商支付项目,里面有个登录功能,已经线上运行了。客户端A 调用生产环境的登录接口B,且线上稳定运行了好几年。某天,公司接到收购了别的公司的项目,需要把这套系统部署在起来,且收购的项目也有对应的客户端C,但是两个客户端和服务端的协议不一样。
需求:收购的项目客户端C,需要做公司原来的项目用户数据打通,连接公司的服务端登录接口B,你能想到几个解决方案?
- 修改就项目B的登录接口,兼容C客户端协议(可能影响线上接口,不稳定)
- 新增全新的登录接口F,采用C客户端协议(和旧的业务逻辑会重复)
- 新增一个转换协议接口,客户端C调用旧的B接口之前,使用转换接口转换下协议(适配器模式,推荐这个方式)
旧的类
java
public class OldModule {
public void moduleA(){
System.out.println("OldModule moduleA");
}
}
接口——当做通信的桥梁
java
public interface TargetModule {
/**
* 和需要整合的类方法名一样
*/
void moduleA();
/**
* 新的方法
*/
void moduleB();
}
适配器
java
/**
* 继承旧的类,实现接口,由于继承旧的类,旧的类中的方法就无需实现
* @author cv大魔王
* @version 1.0
* @date 2021/7/12 19:22
*/
public class Adapter extends OldModule implements TargetModule{
@Override
public void moduleB() {
System.out.println("Adapter ModuleB");
}
}
使用:
java
public static void main(String[] args) {
TargetModule targetModule = new Adapter();
targetModule.moduleA();
targetModule.moduleB();
}