zoukankan      html  css  js  c++  java
  • 产品思维之设计模式-工作流与跨系统单据处理

    一、引子
    在开发业务系统时,常有这种需求:业务流程中(审核流程),需要将业务凭证发送到外部系统进行处理,并根据外部系统的处理结果,做相应的处理。以付款单为例:录入付款单--审核--发送到凭证平台--【凭证平台生成凭证--返回处理结果到本系统】--本系统根据处理结果做不同处理:如果生成成功,流程结束;如果失败,将付款单退回】。这种过程很常见,实现起来也没有特别的难点。由于其存在的普遍性,因此有必要设计出一个通用的实现模式。
    二、设计
    模式中包括几部分:
    1、工作流
    工作流用来处理付款单(常说的单据审核)。在其中的某一个节点上,比如“生成财务凭证”节点,将付款单发送到凭证平台,生成财务凭证,如果生成失败,工作流则路由到人工处理节点,进行人工介入。
    2、业务表单发送程序
    调用对方系统的接口,将凭证发送到对方系统;发送程序,可以被工作流调用。
    3,发送队列
    发送队列存放待发送的单据。发送队列管理程序可以依次发送队列中的单据。
    工作流调用发送程序,如果发送失败,则将单据放到队列中,以备继续发送。
    通用考虑,发送队列可以使用消息队列,处理所有类型的单据,业务系统生产“消息”(付款单发送请求)到消息队列,付款单发送程序订阅“消息”,将付款单发送到凭证平台。

    3、处理结果接收
    前面说过,付款单发送到凭证平台后,本系统需要根据凭证平台的处理结果做不同的后续处理。因此系统要能接收外部系统对单据的处理结果。因为发送付款单到凭证平台、凭证平台生成凭证、处理结果都是异步的。因此要有专门程序来接收处理结果。
    处理结果的接收也可以使用消息队列来实现,凭证平台生产“消息”(处理结果)到消息队列,“业务系统”订阅“消息”,接收凭证生成结果。
    4、处理结果响应
    处理结果收到后放到消息队列,调用处理结果响应程序,将处理结果反馈到响应的处理程序进行后续处理(比如如果处理成功,工作流往下推进一个节点,否则,返回到工作流开始节点)。
    5、工作任务的状态
    如果将“发送凭证到外部系统并等待处理结果”作为一个工作流任务看待的话,这个工作流任务有如下特点:
    (1)任务的执行结果不是实时返回的
    (2)任务的状态除了常规的状态外(新建,挂起,认领,结束),还有一个 “等待结果”的状态。
    (3)单据处理结果响应程序 在得到单据的外部系统的处理结果后,来更新任务的状态为完成,并赋值任务的返回值return value。工作流任务除了有执行状态外,还有执行结果这个属性。
    (4)工作流系统应该加入对“等待结果”这种任务状态的支持。对这种状态的任务,工作流不做任何处理,等待任务的状态 切换到 完成。一旦任务状态为完成,工作流引擎就根据任务的返回码,做对应的处理(推进或者退回,取决于工作流定义的处理逻辑)。

    三、总结
    方案有两个关键点。
    1、发送、状态接收和处理均采用消息队列,或者类似于消息队列的设计模式。消息队列是典型的“订阅”模式,优点:异步调用,解耦,削峰。异步调用可以提高系统性能,解耦提高了系统的可配置性和可扩展性。利用消息队列,还能有效“防重”,避免在网络异常的时候,重复发送处理和接收数据。
    2、扩展了工作流引擎的任务状态,增加了“等待结果”的任务状态。同样等待结果以通过mq来实现。

    其实,这个文章的题目有点大了,也有点文不对题,不改了。以上的思路很简单,关键是要将以上2点实现为公共的业务组件进行复用。通过复用提高系统开发效率,提高系统的质量。

    另:(1)关于mq的基本结构、原理 和实现方法,参见mq的知识。百度一大把呢。
    推荐知乎上的这个帖子:https://www.zhihu.com/question/54152397。有好几个大牛的回答相当有深度和专业,可以一读。
    (2)关于“订阅”模式,是23种设计模式中最常用的几种设计模式之一,也是非常容易理解的模式,大家可以百度,都讲的不错,或者买《design pattern》这本书来读一下,非常经典,架构师必读。

  • 相关阅读:
    初学 Delphi 嵌入汇编[13] 地址参数用 [] 取值
    初学 Delphi 嵌入汇编[17] 逻辑运算
    初学 Delphi 嵌入汇编[11] 用汇编重写一个 Delphi 函数
    初学 Delphi 嵌入汇编[12] 在汇编代码中可以直接使用 Result
    初学 Delphi 嵌入汇编[19] Delphi 的无符号整数类型
    分享:tcpproxy实现
    Socket编程之简单介绍 蓝天下的雨 博客园
    分享:libuv 中文编程指南
    分享:《编程之美》求二叉树中节点的最大距离
    CentOS6.0下编译最新版本boost库
  • 原文地址:https://www.cnblogs.com/senline/p/workflow_crosssys_doc.html
Copyright © 2011-2022 走看看