支付业务的优化(命令模式的应用)

1、业务现状

  所处的公司环境我就不多说了,在上一篇博文中已经说了一下。公司整个业务体系中包含有支付模块,支付的业务分类如下:

  a)发布各类房源

  b)购买各类会员(虽然没用户,但是功能存在)

  c)购买各种服务

  d)购买理财

  大概就这几类了,支付这块的调整主要是在web页面显示的文字上的调整,真正的支付逻辑,几乎是不动的,那优化什么呢?这个主要还是技术层面从软件的灵活性和扩展性考虑进行优化的。其实各个公司的支付业务应该都是差不多的,至少是支付这块的逻辑!整个流程都大差不差的。

2、当前实现

  整个支付流程的流程是调用支付接口,与余额或者第三方支付平台交互,成功后回调完成对应的支付操作。流程图如下:

  现有操作的伪代码如下:

package cn.simple.old;

import cn.simple.old.domain.PayModel;

/**
 * 现状的支付模块的实现伪代码
 *
 * @author ldm
 * @Date 2016年6月22日
 */
public class OldPay {

    public PayModel pay(PayModel model) {

        switch (model.getPayType()) {
        case 1:
            // 余额支付
            model.setPaySuccess(payThird());
            break;
        case 2:
            // 支付宝支付
            model.setPaySuccess(payThird());
            break;
        case 3:
            // 微信支付
            model.setPaySuccess(payThird());
            break;
        case 4:
            // 网银
            model.setPaySuccess(payThird());
            break;
        default:
            model.setPaySuccess(false);
            break;
        }
        if (model.isPaySuccess()) {
            return callback(model);
        } else {
            return model;
        }
    }

    public PayModel callback(PayModel model) {
        switch (model.getType()) {
        case 1:
            // 买会员
            model.setOprSuccess(callBackOpr());
            break;
        case 2:
            // 买服务
            model.setOprSuccess(callBackOpr());
            break;
        case 3:
            // 发房
            model.setOprSuccess(callBackOpr());
            break;
        case 4:
            // 理财
            model.setOprSuccess(callBackOpr());
            break;
        default:
            model.setOprSuccess(false);
            break;
        }
        return model;
    }

    //////////////////////////// 这是模拟第三方支付的(不同的支付方会有不同的实现)/////////////////////////////
    private boolean payThird() {
        // 支付的参数配置。。。
        return true;
    }
    /////////////////////////////// 回调具体操作///////////////////////////////////
    public boolean callBackOpr()
    {
        return true;
    }

}

  从伪代码中看出,这种实现方式,是没大问题的,但是扩展性和灵活性很低。每当增加一个新业务,就必须得更改支付流程的核心类(在switch中增加新的选项),随着业务的增加迭代,又没有明确的下线,和代码优化,导致整个支付类代码非常臃肿,可读性很差。

3、优化实现

  基于现有的支付流程,从扩展性和灵活性的角度出发,对这个现有的业务进行重构和优化。类图如下:

示例关键代码

命令抽象类:

package cn.simple.command.impl;

import cn.simple.command.ICommand;
import cn.simple.pay.IPay;

/**
 * 命令抽象类
 *
 * @author ldm
 * @Date 2016年6月22日
 */
public abstract class AbstractPayCommand implements ICommand {
    protected IPay pay;

    public AbstractPayCommand(IPay pay) {
        this.pay = pay;
    }

    public abstract void setPay(IPay pay);

    /**
     * 执行命令
     *
     * @author ldm
     * @return
     * @Date 2016年6月22日
     */
    public String doCommand() {
        System.out.println("执行命令");
        String payResult = pay.doPay();
        if (payResult.startsWith("1,")) {
            boolean cb = cmdCallback();
            if (cb) {
                payResult += "^1";
            } else {
                payResult += "^0";
            }

            return payResult;
        } else {
            return "^0";
        }

    }

    /**
     * 命令回调
     *
     * @author ldm
     * @return
     * @Date 2016年6月22日
     */
    public abstract boolean cmdCallback();
}

调用者的实现:

package cn.simple.invoker;

import cn.simple.command.impl.AbstractPayCommand;
import cn.simple.command.impl.ServiceCommand;
import cn.simple.pay.impl.Alipay;
/**
 * 购买服务调用
 * @author ldm
 * @Date 2016年6月22日
 */
public class ServiceInvoker {
    public static void main(String[] args) {
        /**
         * 支付方式让用户确定
         */
        AbstractPayCommand cmd = new ServiceCommand(new Alipay());
        String result = cmd.doCommand();
        System.out.println("命令执行结果:"+result);
        if (result.startsWith("1,")) {
            System.out.println("支付成功");
            if (result.endsWith("^0")) {
                System.out.println("操作失败");
            } else {
                System.out.println("操作成功");
            }
        } else {
            System.out.println("支付失败");
        }

    }
}

  对业务代码进行优化后,扩展性和灵活性大大增加。

  a)如果需要增加支付方式,只需要实现特定的接口;

  b)增加新的需要付费服务,也是实现一下抽象命令

4、模型优化

  对当前这么模型在实际生产中可以直接用,也可以进行一些优化后再使用。可以对命令和支付方式进行工厂封装。可以进一步提高灵活性。

完整示例:https://github.com/monkeyming/command

命令模式的介绍可以参考一下:http://www.cnblogs.com/hpuCode/p/5455254.html

时间: 2024-12-28 23:45:43

支付业务的优化(命令模式的应用)的相关文章

【系统知识点】linux基础&优化命令

Xshell上传下载服务器的文件: yum -y install lrzsz sysstat//安装对应软件 sz XXXX//下载 rz XXXX//上传 创建用户: Useradd vrfxie //创建用户 -c comment 指定一段注释性描述. -d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录. -g 用户组 指定用户所属的主用户组. -G 用户组,用户组 指定用户所属的附加组. -s Shell文件 指定用户的登录Shell. #可以设置为/sbin

活用命令模式

在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活. 本文的目的 本文的目的要旨在于 了解Command Design Pattern 在实用示例中尽力利用.net的语言特色去优化Command Design Pattern令到我们更容易去使用它 从应用中理解Command Design P

[超次元设计模式]——命令模式

1. 为什么要有命令模式 软件构建过程中.行为请求者与行为调用者可能有强耦合的情况.如下所示 if (type == a) { do_a() } else if (type == b) { do_b() } else if (type == c) { do_c() } ... 这样的代码是非常繁杂且高耦合的,所以需要一种模式优化掉它. 可能需要进行行为撤销等操作,这样编码可能会非常麻烦. 所以,命令模式,要做的就是,将行为封装成对象,以解决这个问题. 2. 命令模式的定义 命令模式: 将请求(行

5.5 进入编辑模式 5.6 vim命令模式 5.7 vim实践

5.5 进入编辑模式 5.6 vim命令模式 5.7 vim实践 扩展 vim的特殊用法 http://www.apelearn.com/bbs/thread-9334-1-1.html vim常用快捷键总结 http://www.apelearn.com/bbs/thread-407-1-1.html vim快速删除一段字符 http://www.apelearn.com/bbs/thread-842-1-1.html vim乱码 http://www.apelearn.com/bbs/thr

Ubuntu命令模式基础

Ubuntu是一个自由.开源.基于Debian的Linux发行版.在ubuntu的基础上,又衍生其它各具特色的Linux发行版.首先是一个操作系统,操作系统用于管理电脑硬件.要发挥出电脑的作用,还得依靠安装各种应用软件. 其相关的简单命令如下: (1)查看当前文件夹下的目录 ①.ls (list的缩写)命令用于列出文件和目录.默认上,他会列出当前目录的内容.带上参数后,可以以不同的方式显示.如图: ls命令可以列出当前目录的内容.dir命令是ls命令的一个别名,也是directory的缩写.通常

【游戏设计模式】之二 实现撤消重做、回放系统的神器:命令模式

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/52663057 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 这篇文章将与大家一起探索游戏开发中命令模式的用法. 命令模式的成名应用是实现诸如撤消,重做,回放,时间倒流之类的功能.如果你想知道<Dota2>中的观战系统.<魔兽争霸3>中的录像系统.<守望先锋>

命令模式

1.命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化:对请求排列或记录请求日志,以及支持可以撤销的操作. 2.优点:(1).他能比较容易的设计一个命令队列:(2).在需要的情况下,比较容易的将命令记入日志:(3).允许接收请求的一方决定是否否决请求:(4).可以容易地实现对请求的撤销和重做:(5).由于加进新的具体命令类不影响其它类,因此增加新的具体命令很容易.(6).把请求一个操作的对象与指导怎么执行操作对象分隔开. 3.注意:不要为代码添加基于猜测的.实际不需要的

【设计模式】 模式PK:命令模式VS策略模式

1.概述 命令模式和策略模式的类图确实很相似,只是命令模式多了一个接收者(Receiver)角色.它们虽然同为行为类模式,但是两者的区别还是很明显的.策略模式的意图是封装算法,它认为"算法"已经是一个完整的.不可拆分的原子业务(注意这里是原子业务,而不是原子对象),即其意图是让这些算法独立,并且可以相互替换,让行为的变化独立于拥有行为的客户:而命令模式则是对动作的解耦,把一个动作的执行分为执行对象(接收者角色).执行行为(命令角色),让两者相互独立而不相互影响. 我们从一个相同的业务需

设计模式—命令模式

1 概述 将一个请求封装为一个对象(即我们创建的Command对象),从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 2 解决的问题 在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录.撤销或重做.事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适. 3 模式中的角色 3.1 抽象命令(Command):定义命令的接口,声明执行的方法. 3.2 具体命令(ConcreteCommand):具体命令,实现要执