【java实现设计模式】深入浅出讲适配器模式:以多支付渠道整合为例

该文章已生成可运行项目,

一、模式定义与价值

适配器模式(Adapter Pattern)是一种结构型设计模式,其核心价值在于解决接口不兼容问题。如同现实中的电源转换器,它能在不修改已有代码的基础上,让原本不兼容的接口协同工作。该模式符合开闭原则,有效提高系统扩展性。

二、典型业务场景

某电商系统需要接入多个支付渠道(支付宝、微信、银联),各渠道接口差异显著:

  • 支付宝:AliPayClient#aliPay(String orderNo, BigDecimal amount)
  • 微信:WechatPayClient#wechatPay(String userId, BigDecimal amount)
  • 银联:UnionPayClient#processPayment(Map<String, Object> params)

系统需要统一支付入口,降低业务层与具体支付实现的耦合度。

三、模式实现详解

1. 统一支付接口定义

public interface PayService {
    /**
     * 统一支付接口
     * @param request 支付请求封装
     * @return 支付平台交易号
     */
    String pay(PayRequest request);
}

// 支付请求参数封装
@Data
public class PayRequest {
    private String orderNo;
    private BigDecimal amount;
    private String userId;
    // 其他扩展字段...
}

2. 支付宝适配器实现

public class AlipayAdapter implements PayService {
    private final AliPayClient aliPayClient;

    public AlipayAdapter(AliPayClient aliPayClient) {
        this.aliPayClient = aliPayClient;
    }

    @Override
    public String pay(PayRequest request) {
        // 参数适配转换
        String orderNo = request.getOrderNo();
        BigDecimal amount = request.getAmount();
        
        // 调用原生接口
        return aliPayClient.aliPay(orderNo, amount);
    }
}

3. 微信支付适配器实现

public class WechatAdapter implements PayService {
    private final WechatPayClient wechatClient;

    public WechatAdapter(WechatPayClient wechatClient) {
        this.wechatClient = wechatClient;
    }

    @Override
    public String pay(PayRequest request) {
        // 参数适配
        String userId = request.getUserId();
        BigDecimal amount = request.getAmount();

        // 调用原生接口
        return wechatClient.wechatPay(userId, amount);
    }
}

4. 银联支付适配器(展示复杂参数处理)

public class UnionPayAdapter implements PayService {
    private final UnionPayClient unionPayClient;

    public UnionPayAdapter(UnionPayClient unionPayClient) {
        this.unionPayClient = unionPayClient;
    }

    @Override
    public String pay(PayRequest request) {
        // 构建银联专用参数
        Map<String, Object> params = new HashMap<>();
        params.put("merchantOrderNo", request.getOrderNo());
        params.put("txnAmt", request.amount.multiply(BigDecimal.valueOf(100)).longValue());
        params.put("userId", request.getUserId());

        // 调用原生接口
        return unionPayClient.processPayment(params);
    }
}

四、客户端调用示例

public class PaymentController {
    private Map<PayChannel, PayService> payServices = new EnumMap<>(PayChannel.class);

    @PostConstruct
    public void init() {
        payServices.put(PayChannel.ALIPAY, new AlipayAdapter(new AliPayClient()));
        payServices.put(PayChannel.WECHAT, new WechatAdapter(new WechatPayClient()));
        payServices.put(PayChannel.UNIONPAY, new UnionPayAdapter(new UnionPayClient()));
    }

    public String handlePayment(PayChannel channel, PayRequest request) {
        PayService payService = payServices.get(channel);
        return payService.pay(request);
    }
}

五、模式优势分析

  1. 解耦价值:业务层与具体支付实现完全解耦
  2. 可维护性:新增支付渠道只需添加适配器,无需修改现有代码
  3. 统一入口:标准化支付接口,降低调用复杂度
  4. 异常处理:可在适配器中统一处理各渠道的异常码转换

六、适用场景扩展

  1. 日志框架适配:SLF4J 作为门面模式,底层对接 Log4j/Logback
  2. 数据格式转换:XML 与 JSON 格式互转适配
  3. 设备驱动开发:统一操作接口适配不同硬件设备
  4. 第三方SDK封装:不同云服务商的OSS操作适配

七、架构思考

  • 对象适配器 vs 类适配器:Java推荐使用对象组合方式(如本文示例),避免多重继承带来的复杂度
  • 与外观模式区别:适配器侧重接口转换,外观模式侧重接口简化
  • 性能考量:在高频调用场景需注意适配器带来的间接调用开销

通过适配器模式,我们成功将差异化的支付接口转换为统一的服务接口。这种设计使得支付渠道的增减不再影响核心业务流程,有效提高了系统的可维护性和扩展性。开发者在实际应用中可根据业务复杂度,灵活选择适配粒度和实现方式。

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值