当前位置: 首页 > article >正文

基于命令行模式设计退款请求处理

前言

        这篇文章的业务背景是基于我的另一篇文章:

 

对接苹果支付退款退单接口-CSDN博客

       

        然后就是说设计模式是很开放的东西,可能我觉得合适,你可能觉得不合适,这里只是做下讨论,没有一定要各位同意的意思....

相关图文件

        这里我先把相关的图文件放上来,可能看着会比较清晰点

代码逻辑

        先把每个类的代码放上来一下,首先是接口

涉及java类

AppNotifyCommand(这个没啥好说的)

public interface AppNotifyCommand<T extends AppStoreNotifyDto> {

    //命令定义,可以参考官网
    //https://developer.apple.com/documentation/appstoreservernotifications/notification_type
    String REFUND_COMMAND_NAME = "REFUND";



    String NOT_FOUND_COMMAND_NAME = "NOT_FOUND";

    /**
     *  获取命令名称
     * @return
     */
    String getCommandName();

    /**
     * 执行命令
     * @param T
     */
    String execute(T T);
}

AbstractAppNotifyCommand(抽象类,给子类继承的,还是比较有意义的)

@Slf4j
public abstract class AbstractAppNotifyCommand<T extends AppStoreNotifyDto> implements AppNotifyCommand<T>{
    @Override
    public String getCommandName() {
        String commandName = doGetCommandName();
        if(StringUtil.isBlank(commandName)) {
            throw new IllegalArgumentException("commandName为空");
        }
        return commandName;
    }

    @Override
    public String execute(T T) {
        try {
            return doExecute(T);
        } catch (Exception e) {
            log.error("执行具体命令时发生异常", e);
            throw new AppException("执行具体命令时发生异常", e);
        }
    }

    protected abstract String doGetCommandName();

    protected abstract String doExecute(T T) throws Exception;

}

AppRefundCommand(退款处理类)

@Service
public class AppRefundCommand extends AbstractAppNotifyCommand<AppStoreNotifyDto> {

    @Override
    protected String doGetCommandName() {
        return REFUND_COMMAND_NAME;
    }

    @Override
    protected String doExecute(AppStoreNotifyDto appStoreNotifyDto) throws Exception{

//        //获取解密数据
//        AppStoreDecodedPayloadDto appStoreDecodedPayloadDto = parseTransactionInfo(appStoreNotifyDto);
//
//        //退款逻辑处理.....


        return "执行完成了";
    }
}

AppNotFoundCommand(找不到对应的处理命令时也写了一个处理类)

@Slf4j
@Service
public class AppNotFoundCommand extends AbstractAppNotifyCommand<AppStoreNotifyDto> {
    @Override
    protected String doGetCommandName() {
        return NOT_FOUND_COMMAND_NAME;
    }

    @Override
    protected String doExecute(AppStoreNotifyDto appStoreNotifyDto) throws Exception {
        log.info("目前{}的命令没有进行处理,返回空字符串", appStoreNotifyDto.getNotificationType());
        return "";
    }
}

        上面的几个类都是基础类,没啥好说的,主要是下面这个类,维护了对外的接口,如下

@Service
@Slf4j
public class AppCommandComposite {


    @Resource
    private List<AppNotifyCommand<AppStoreNotifyDto>> appNotifyCommandList;

    private Map<String, AppNotifyCommand<AppStoreNotifyDto>> appNotifyCommandMap;

    @PostConstruct
    public void init() {

        appNotifyCommandMap = new ConcurrentHashMap<>();

        //循环放置数据
        for (AppNotifyCommand<AppStoreNotifyDto> appNotifyCommand : appNotifyCommandList) {
            appNotifyCommandMap.put(appNotifyCommand.getCommandName(), appNotifyCommand);
        }
    }

    /**
     * 执行命令
     * @param appStoreNotifyPayLoadDto
     * @return
     */
    public String handleCommand(AppStoreNotifyPayLoadDto appStoreNotifyPayLoadDto) {
        try {

            //解密基础数据
            AppStoreNotifyDto appStoreNotifyDto = AppStoreReturnUtil.verifyAndGet(appStoreNotifyPayLoadDto.getSignedPayload());

            log.info("开始执行苹果的{}通知命令", appStoreNotifyDto.getNotificationType());

            //获取安全的执行器执行
            AppNotifyCommand<AppStoreNotifyDto> appNotifyCommand = appNotifyCommandMap.get(appStoreNotifyDto.getNotificationType());

            String result = safeAppNotifyCommand(appNotifyCommand).execute(appStoreNotifyDto);

            log.info("执行苹果的{}通知命令完成,返回的数据为{}", appStoreNotifyDto.getNotificationType(), result);

            return result;
        } catch (Exception e) {
            log.error("解析苹果加密数据失败", e);
            throw new AppException("解析苹果加密数据失败");
        }
    }

    //获取安全的执行器执行
    private AppNotifyCommand<AppStoreNotifyDto> safeAppNotifyCommand(AppNotifyCommand<AppStoreNotifyDto> appNotifyCommand) {

        if(appNotifyCommand == null) {
            return appNotifyCommandMap.get(AppNotifyCommand.NOT_FOUND_COMMAND_NAME);
        }

        return appNotifyCommand;
    }
}

  设计亮点

        主要在AppCommandComposite类上面,主要用到了如下的一些亮点设计

1. 基于Spring 容器功能收集 以下数据

    @Resource
    private List<AppNotifyCommand<AppStoreNotifyDto>> appNotifyCommandList;

2. 基于Spring Bean的生命周期初始化方法 @PostConstruct 收集到map里面去

   private Map<String, AppNotifyCommand<AppStoreNotifyDto>> appNotifyCommandMap;

3. 对外提供handleCommand 方法, 逻辑如下

        首先对数据进行解密, 这在另外一篇文章说了,这里就不赘述了

        其次根据苹果返回的notificationType获取到具体的命令处理器

        精华在于,获取不到的时候会返回AppNotFoundCommand进行处理,而我们可以打印日志,表明苹果发了哪些请求,到时如果需要处理可以添加AppNotifyCommand实现类处理即可

结语

        总的来说逻辑并不复杂,至于这样设计好不好每个人的看法就当不一样了,我个人是觉得这样的话可以统一很多逻辑,不需要后续的人员再参与,

        不好的地方在于没有专门研究过设计模式的人可能看起来会很复杂,但是只要写好对应的文档其实就可了

        


http://www.kler.cn/a/145488.html

相关文章:

  • [STM32 - 野火] - - - 固件库学习笔记 - - -十一.电源管理系统
  • STM32_SD卡的SDIO通信_基础读写
  • 阿里巴巴开发规范手册MySQL
  • 从零到一:Spring Boot 与 RocketMQ 的完美集成指南
  • SQL注入漏洞之基础数据类型注入 字符 数字 搜索 XX 以及靶场实例哟
  • MySQL基于gtid的主从同步配置
  • App 设计工具
  • Springmvc原理解析
  • C语言第三十弹---打印一个整数的每一位数
  • 数据结构 / day04 作业
  • 微服务-京东秒杀
  • 虹科分享 | AR世界揭秘:从二维码的起源到数据识别与位姿技术的奇妙融合!
  • 频剪辑软件Corel VideoStudio 会声会影2024最新7大新全新功能解析
  • 脚本自动化定制开发:实现高效工作的魔法钥匙
  • steam/csgo搬砖项目真能月入过万吗?到底真的假的
  • Qt手写ListView
  • kafka详细讲解与安装
  • 2023年亚太杯数学建模A题解题思路(*基于OpenCV的复杂背景下苹果目标的识别定位方法研究)
  • MVCC多版本并发控制相关面试题整理
  • Python基础【三】--数据类型-Number【2023.11.23】
  • 吴恩达《机器学习》10-4-10-5:诊断偏差和方差、正则化和偏差/方差
  • 区间第k小数 (可持久化线段树、主席树)
  • 计算机组成原理4
  • 【华为OD】B\C卷真题 100%通过:找城市 多叉树实现 python源码
  • python 点云las生成深度图
  • VMware 安装 Centos7 超详细过程