利用责任链模式解耦多平台(美团/饿了么)霸王餐接口的适配逻辑

利用责任链模式解耦多平台(美团/饿了么)霸王餐接口的适配逻辑

在构建支持多外卖平台(如美团、饿了么)的"霸王餐"营销系统时,不同平台的接口协议、认证方式、参数结构差异显著。若将各平台逻辑硬编码在业务方法中,会导致代码高度耦合、难以维护和扩展。责任链模式(Chain of Responsibility Pattern) 能有效解耦平台适配逻辑,使系统具备良好的可扩展性与清晰的职责划分。本文将基于 Java 实现一个支持美团与饿了么的霸王餐核销服务,并展示如何通过责任链动态路由请求。

定义统一请求与响应模型

首先抽象出平台无关的业务请求与结果:

java 复制代码
package juwatech.cn.model;

public class FreeMealRequest {
    private String platform; // "meituan" 或 "eleme"
    private String orderId;
    private String userId;
    private String activityId;

    // getters and setters
}

public class FreeMealResult {
    private boolean success;
    private String message;
    private String thirdPartyOrderId;

    // constructors, getters and setters
}

抽象处理器基类

定义责任链节点的通用接口与抽象基类:

java 复制代码
package juwatech.cn.handler;

import juwatech.cn.model.FreeMealRequest;
import juwatech.cn.model.FreeMealResult;

public abstract class FreeMealHandler {
    protected FreeMealHandler nextHandler;

    public void setNext(FreeMealHandler handler) {
        this.nextHandler = handler;
    }

    public FreeMealResult handle(FreeMealRequest request) {
        if (supports(request)) {
            return doHandle(request);
        }
        if (nextHandler != null) {
            return nextHandler.handle(request);
        }
        throw new UnsupportedOperationException("Unsupported platform: " + request.getPlatform());
    }

    protected abstract boolean supports(FreeMealRequest request);
    protected abstract FreeMealResult doHandle(FreeMealRequest request);
}

美团平台适配器实现

java 复制代码
package juwatech.cn.handler.impl;

import juwatech.cn.handler.FreeMealHandler;
import juwatech.cn.model.FreeMealRequest;
import juwatech.cn.model.FreeMealResult;
import juwatech.cn.client.MeituanApiClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MeituanFreeMealHandler extends FreeMealHandler {

    @Autowired
    private MeituanApiClient meituanClient;

    @Override
    protected boolean supports(FreeMealRequest request) {
        return "meituan".equalsIgnoreCase(request.getPlatform());
    }

    @Override
    protected FreeMealResult doHandle(FreeMealRequest request) {
        try {
            String response = meituanClient.verifyFreeMeal(
                request.getOrderId(),
                request.getUserId()
            );
            return new FreeMealResult(true, "Success", extractThirdOrderId(response));
        } catch (Exception e) {
            return new FreeMealResult(false, "Meituan API error: " + e.getMessage(), null);
        }
    }

    private String extractThirdOrderId(String response) {
        // 解析美团返回的JSON获取订单ID
        return "MT_" + System.currentTimeMillis();
    }
}

饿了么平台适配器实现

java 复制代码
package juwatech.cn.handler.impl;

import juwatech.cn.handler.FreeMealHandler;
import juwatech.cn.model.FreeMealRequest;
import juwatech.cn.model.FreeMealResult;
import juwatech.cn.client.ElemeApiClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ElemeFreeMealHandler extends FreeMealHandler {

    @Autowired
    private ElemeApiClient elemeClient;

    @Override
    protected boolean supports(FreeMealRequest request) {
        return "eleme".equalsIgnoreCase(request.getPlatform());
    }

    @Override
    protected FreeMealResult doHandle(FreeMealRequest request) {
        try {
            String token = elemeClient.getAccessToken();
            String response = elemeClient.verifyTrialMeal(
                token,
                request.getActivityId(),
                request.getOrderId()
            );
            return new FreeMealResult(true, "Success", extractElemeOrderId(response));
        } catch (Exception e) {
            return new FreeMealResult(false, "Eleme API error: " + e.getMessage(), null);
        }
    }

    private String extractElemeOrderId(String response) {
        return "EL_" + System.currentTimeMillis();
    }
}

责任链装配与调用入口

通过 Spring 配置组装责任链:

java 复制代码
package juwatech.cn.config;

import juwatech.cn.handler.FreeMealHandler;
import juwatech.cn.handler.impl.ElemeFreeMealHandler;
import juwatech.cn.handler.impl.MeituanFreeMealHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HandlerChainConfig {

    @Bean
    public FreeMealHandler freeMealHandlerChain(MeituanFreeMealHandler meituan,
                                                ElemeFreeMealHandler eleme) {
        meituan.setNext(eleme);
        return meituan;
    }
}

业务服务中注入链头并调用:

java 复制代码
package juwatech.cn.service;

import juwatech.cn.handler.FreeMealHandler;
import juwatech.cn.model.FreeMealRequest;
import juwatech.cn.model.FreeMealResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class FreeMealService {

    @Autowired
    private FreeMealHandler handlerChain;

    public FreeMealResult processFreeMeal(FreeMealRequest request) {
        return handlerChain.handle(request);
    }
}

新增平台的扩展方式

当未来需接入"京东到家"等新平台时,只需:

  1. 新增 JddjFreeMealHandler extends FreeMealHandler
  2. 实现 supportsdoHandle
  3. HandlerChainConfig 中将其加入链尾

无需修改现有业务逻辑,符合开闭原则。

本文著作权归吃喝不愁app开发者团队,转载请注明出处!

相关推荐
常利兵11 分钟前
Android Gradle 构建脚本现代化:Kotlin DSL (.kts) 与 Groovy DSL 深度对比与实战指南
android·开发语言·kotlin
TheNextByte112 分钟前
如何在PC和Android平板之间传输文件
android·gitee·电脑
Greenland_1227 分钟前
Android 混淆与混淆后bug日志问题定位
android·bug
baidu_2474386133 分钟前
Android kotlin 定时n秒完成时回调,含暂停和继续
android·kotlin
2501_9371892339 分钟前
TV 电视影视大全:全场景高清观影技术解析
android·源码·源代码管理
2501_937154931 小时前
TV 电视影视大全:全场景高清观影技术解析
android·源码·源代码管理·机顶盒
峥嵘life1 小时前
Android16 【GSI】CtsMediaCodecTestCases等一些列Media测试存在Failed项
android·linux·运维·服务器·学习
玉梅小洋1 小时前
Android SDK 安装指南(MacOS 和 Windows)
android·windows·macos·sdk
2501_916007471 小时前
没有 Mac 用户如何上架 App Store,IPA生成、证书与描述文件管理、跨平台上传
android·macos·ios·小程序·uni-app·iphone·webview
常利兵1 小时前
Spring Boot 3 多数据源整合 Druid:监控页面与控制台 SQL 日志配置实战
android·spring boot·sql