AIGC标识 Java23中设计模式适配器的实战场景,修改旧依赖包中的方法,实现功能

场景设定:
我们引入外部jar依赖包 old-third-sdk.jar,包里的源码我们无法修改、只能调用。
依赖包里的类不止一个支付方法,还有一大堆配套业务方法;
我们用继承适配器实现新旧接口适配,同时演示:重写父类需要改变的方法,且剩余的方法会不会被影响?需要在重写或者调用?

一、依赖包内部原有类(只读,无法修改)

// 位于第三方依赖包 old-third-sdk.jar
public class OldPaySdk {

    // 方法1:老旧支付核心方法(需要适配改造)
    public void sendOldPay(String orderNo, Integer money) {
        System.out.println("【依赖包原生】发起老式支付:订单:" + orderNo + ",金额:" + money);
    }

    // 方法2:查询余额(不需要改动,直接沿用)
    public Integer getBalance(String accountId) {
        System.out.println("【依赖包原生】查询账户余额");
        return 10000;
    }

    // 方法3:关闭支付通道(工具方法,原样保留)
    public void closeChannel() {
        System.out.println("【依赖包原生】关闭支付通道");
    }

    // 更多其他附属方法...
}

二、项目自定义新标准接口

// 我们项目统一支付规范
public interface NewPayApi {
    void pay(String orderId, Integer amount);
}

三、继承适配器:继承依赖类 + 实现新接口 + 重写父类方法

/**
 * 适配器:extends 依赖包里的OldPaySdk
 * 1. 自动继承依赖包所有public方法:sendOldPay、getBalance、closeChannel 全部拿到
 * 2. 重写父类sendOldPay,修改原有逻辑
 * 3. 实现新项目接口完成适配
 */
public class PayAdapter extends OldPaySdk implements NewPayApi {

    // ========== 1、重写依赖包原生支付方法 ==========
    @Override
    public void sendOldPay(String orderNo, Integer money) {
        System.out.println("【适配器重写】前置校验参数、统一日志、异常捕获");
        // 可选:可以调用父类原版逻辑 super.sendOldPay(...)
        super.sendOldPay(orderNo, money);
        System.out.println("【适配器重写】支付完成后置处理");
    }

    // ========== 2、实现新项目标准接口 ==========
    @Override
    public void pay(String orderId, Integer amount) {
        // 内部调用自己重写后的支付方法
        sendOldPay(orderId, amount);
    }
}

注意:这里只重写父类我们需要调用的方法,剩余的方法完全不受影响,还是继续从旧的依赖包中进行调用

四、客户端调用测试,直观区分效果

public class Client {
    public static void main(String[] args) {
        PayAdapter adapter = new PayAdapter();

        System.out.println("=====1.调用适配后的新接口(业务主流调用)=====");
        adapter.pay("ORD001", 299);

        System.out.println("\n=====2.直接调用被重写的依赖包原有方法=====");
        adapter.sendOldPay("ORD002", 599);

        System.out.println("\n=====3.调用依赖包里其余未重写的普通方法=====");
        Integer balance = adapter.getBalance("ACC123");
        System.out.println("余额:" + balance);
        adapter.closeChannel();
    }
}

运行结果

=====1.调用适配后的新接口(业务主流调用)=====
【适配器重写】前置校验参数、统一日志、异常捕获
【依赖包原生】发起老式支付:订单:ORD001,金额:299
【适配器重写】支付完成后置处理

=====2.直接调用被重写的依赖包原有方法=====
【适配器重写】前置校验参数、统一日志、异常捕获
【依赖包原生】发起老式支付:订单:ORD002,金额:599
【适配器重写】支付完成后置处理

=====3.调用依赖包里其余未重写的普通方法=====
【依赖包原生】查询账户余额
余额:10000
【依赖包原生】关闭支付通道

五、核心结论:依赖包里剩下的其他方法受不受影响?

  1. 被你重写的方法
    父类原本逻辑被覆盖,无论通过新接口调用、还是直接调用原方法名,执行的都是适配器重写后的代码;
    想要调用依赖包原版逻辑,只能在适配器内部写 super.方法名()

  2. 依赖包里其余没有重写的所有方法(getBalance、closeChannel)
    完全不受任何影响
    在Java中,适配器通过继承实现,调用时依旧执行依赖jar内部原本的源码,不会被修改、不会被包装。

  3. 边界补充

  • 依赖包里 private 私有方法:继承拿不到,完全无关;
  • final 方法:无法重写,只能原样调用;
  • 静态方法:不存在重写,只会隐藏,一般不会拿来做适配。

六、继承方式在这里的隐患(对接第三方jar弊端)

  1. 单继承限制:只能继承这一个支付SDK,无法同时对接微信、支付宝多个第三方依赖;
  2. 耦合极强:依赖包升级改动任意方法,适配器极易报错;
  3. 如果你不需要用到父类大部分工具方法,继承会白白继承一堆冗余代码。

七、对比主流组合写法(无继承)

适配器只持有依赖对象,不会继承全部方法,不会污染空间,其余方法按需调用,更加稳妥:

public class PayAdapter implements NewPayApi {
    // 持有依赖对象,而非继承
    private OldPaySdk sdk = new OldPaySdk();

    @Override
    public void pay(String orderId, Integer amount) {
        sdk.sendOldPay(orderId, amount);
    }
}
注意:这里介绍是根据上述中例子的使用方式,简化的一种。因为上述中描述的业务比较复杂,不太适合用适配器模式。一般适配器模式是放在变化较小的场景中使用最合适。
posted @ 2026-08-10 22:05  浮丶尘  阅读(6)  评论(0)    收藏  举报