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

前言

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

 

对接苹果支付退款退单接口-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实现类处理即可

结语

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

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

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/183400.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Python的turtle模块绘制钢铁侠图案

1.1引言&#xff1a; 在Python中&#xff0c;turtle模块是一个非常有趣且强大的工具&#xff0c;它允许我们以一个可视化和互动的方式学习编程。在本博客中&#xff0c;我们将使用turtle模块来绘制钢铁侠的图案。通过调用各种命令&#xff0c;我们可以引导turtle绘制出指定的图…

Unity UGUI的HorizontalLayoutGroup(水平布局)组件

Horizontal Layout Group | Unity UI | 1.0.0 1. 什么是HorizontalLayoutGroup组件&#xff1f; HorizontalLayoutGroup是Unity UGUI中的一种布局组件&#xff0c;用于在水平方向上对子物体进行排列和布局。它可以根据一定的规则自动调整子物体的位置和大小&#xff0c;使它…

详解深度学习中的图神经网络GNN

引言 图神经网络GNN是深度学习的一个分支。 深度学习的四个分支对应了四种常见的数据格式&#xff0c;前馈神经网络FNN处理表格数据&#xff0c;表格数据可以是特征向量&#xff0c;卷积神经网络CNN处理图像数据&#xff0c;循环神经网络RNN处理时序数据&#xff0c;图神经网…

NLP的使用

参考&#xff1a; Apache openNLP 简介 - 链滴 (ld246.com) opennlp 模型下载地址&#xff1a;Index of /apache/opennlp/models/ud-models-1.0/ (tencent.com) OpenNLP是一个流行的开源自然语言处理工具包&#xff0c;它提供了一系列的NLP模型和算法。然而&#xff0c;Open…

手写数字可视化_Python数据分析与可视化

手写数字可视化 手写数字流形学习 手写数字 手写数字无论是在数据可视化还是深度学习都是一个比较实用的案例。 数据在sklearn中&#xff0c;包含近2000份8 x 8的手写数字缩略图。 首先需要先下载数据&#xff0c;然后使用plt.imshow()对一些图形进行可视化&#xff1a; 打开c…

新材料制造ERP用哪个好?企业应当如何挑选适用的

有些新材料存在特殊性&#xff0c;并且在制造过程中对车间、设备、工艺、人员等方面提出更高的要求。还有些新材料加工流程复杂&#xff0c;涉及多种材料的请购、出入库、使用和管理等环节&#xff0c;解决各个业务环节无缝衔接问题是很多制造企业面临的管理难题。 新材料制造…

计算机网络——物理层相关习题(计算机专业考研全国统考历年真题)

目录 2012-34 原题 答案 解析 2018-34 原题 答案 解析 2009/2011-34 原题 答案 解析 2016-34 原题 答案 解析 2014-35/2017-34 原题 答案 解析 2013-34 原题 答案 解析 2015-34 原题 答案 解析 物理层的协议众多&#xff0c;这是因为物理层…

VSDX Annotator v1.16.1(Visio 绘图注释工具)

VSDX Annotator是一款在Mac上操作MSVisio绘图的工具&#xff0c;提供了广泛的注释可能性&#xff0c;以及在多平台环境中共享可视文档。它确保共有12个注释工具&#xff0c;并允许添加注释、标注、注释、块、图形文件等。该应用程序允许用户在Mac上查看Visio流程图、图表、方案…

Redis集群环境各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的解决方式

原创/朱季谦 在搭建Redis5.x版本的集群环境曾出现各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的情况&#xff0c;故而把解决方式记录下来。 在以下三台虚拟机机器搭建Redis集群—— 192.168.200.160192.168.200.161192.168.200.162启动三台Redis集…

Element中el-table组件右侧空白隐藏-滚动条

开发情况&#xff1a; 固定table高度时&#xff0c;出现滚动条&#xff0c;我们希望隐藏滚动条&#xff0c;或修改滚动条样式&#xff0c;出现table右边出现15px 的固定留白。 代码示例 <el-table class"controlTable" header-row-class-name"controlHead…

springboot+jsp学生健康体检档案评估系统_ju8pu

本基于Java的学生健康档案管理信息系统采用Java语言来进行开发&#xff0c;从角色上分为管理员&#xff0c;辅导员&#xff0c;档案管理员和学生几个具体功能如下 &#xff08;1&#xff09;管理员部分功能主要包括&#xff0c;个人中心&#xff0c;档案员管理&#xff0c;辅…

C#,数值计算——多项式插值与外推插值(Poly2D_interp)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Object for two-dimensional polynomial interpolation on a matrix.Construct /// with a vector of x1 values, a vector of x2 values, a matrix of tabulated /// func…

STM32:基本定时器原理和定时程序

一、初识定时器TIM 定时器就是计数器&#xff0c;定时器的作用就是设置一个时间&#xff0c;然后时间到后就会通过中断等方式通知STM32执行某些程序。定时器除了可以实现普通的定时功能&#xff0c;还可以实现捕获脉冲宽度&#xff0c;计算PWM占空比&#xff0c;输出PWM波形&am…

编程参考 - C++ Code Review: 一个计算器的项目

GitHub - jroelofs/calc: Toy Calculator Toy Calculator 1&#xff0c;拿到一个project&#xff0c;第一眼看&#xff0c;没有配置文件&#xff0c;说明没有引入持续集成系统&#xff0c;continuous integration system。 2&#xff0c;然后看cmake文件&#xff0c;使用的子…

Java基层卫生健康云综合管理(云his)系统源码

云HIS&#xff08;Cloud-Based Healthcare Information System&#xff09;是基于云计算的医院健康卫生信息系统。它运用云计算、大数据、物联网等新兴信息技术&#xff0c;按照现代医疗卫生管理要求&#xff0c;在一定区域范围内以数字化形式提供医疗卫生行业数据收集、存储、…

【LeetCode刷题-链表】--61.旋转链表

61.旋转链表 方法&#xff1a; 记给定的链表的长度为n,注意当向右移动的次数k>n时&#xff0c;仅需要向右移动k mod n次即可&#xff0c;因为每n次移动都会让链表变为原状 将给定的链表连接成环&#xff0c;然后将指定位置断开 /*** Definition for singly-linked list.*…

基于element自动表单设计

需求是根据JSON文件生成表单&#xff0c;包含配置和自动model属性以及表单验证&#xff0c;数据回显。 目录 动态表单数据示例&#xff1a; 表单设置JSON示例&#xff1a; 表单输入JSON示例&#xff1a; 表单按钮JSON示例&#xff1a; 抛出数据示例&#xff1a; 动态表单…

【一文搞定】在Docker中搭建centos7远程桌面环境(Xfce、Gnome两种方式)

目录 前言一、基于GNOME构建远程桌面二、基于Xfce构建远程桌面&#xff08;轻量级&#xff09; 前言 本文提供两种安装方式&#xff0c;均自己测试过&#xff0c;最后还是选择了Xfce&#xff0c;因为它比较轻量级&#xff0c;占用资源较少。大家也可以都试试&#xff0c;比较感…