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

前言

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

 

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

       

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

相关图文件

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

基于命令行模式设计退款请求处理_第1张图片

代码逻辑

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

涉及java类

AppNotifyCommand(这个没啥好说的)

public interface AppNotifyCommand {

    //命令定义,可以参考官网
    //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 implements AppNotifyCommand{
    @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 {

    @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 {
    @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> appNotifyCommandList;

    private Map> appNotifyCommandMap;

    @PostConstruct
    public void init() {

        appNotifyCommandMap = new ConcurrentHashMap<>();

        //循环放置数据
        for (AppNotifyCommand 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 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 safeAppNotifyCommand(AppNotifyCommand appNotifyCommand) {

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

        return appNotifyCommand;
    }
}

  设计亮点

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

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

    @Resource
    private List> appNotifyCommandList;

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

   private Map> appNotifyCommandMap;

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

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

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

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

结语

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

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

        

你可能感兴趣的:(设计模式相关,java,开发语言,设计模式,命令模式)