• 『设计』一个简单的 流程引擎


    项目原因:

    之前参与过一些 工作流 的项目,都是基于 某些 机构现有的 工作流引擎。

    项目进行中,最闹心的 莫过于 业务代码 和 流程代码 的 混淆一起。

     

    见过的工作流是怎样的:

    >首先一个基于 Silverlight 的 流程UI设计器; 通过设计器 得到一个 流程XML 和 布局JSON 两个文件(布局JSON文件当然对 后期运行是 没有用的);

    >业务单据 填写信息,点击“保存”,执行:保存单据数据,从 流程引擎 读取 XML 得到 流程对象,设置下一步 跳转 节点 N1,分发待办;

    >审批单据 填写意见,点击“审批”,执行:修改单据状态,从 流程引擎 读取 XML 得到 流程对象,设置下一步 跳转 节点 N2,分发待办;

    >审批单据 填写意见,点击“驳回”,执行:修改单据状态,从 流程引擎 读取 XML 得到 流程对象,通过条件,设置下一步 跳转 节点 N1  或者 N0 或者 NX,分发待办;

    于是,每一个 单据 的 按钮事件  都得 调用一串 工作流代码,跳转到 哪个流程 也是 代码 说了算。

     

    于是,我开始质疑:流程设计器中 的 连线,连线上的判断条件 莫非就是 装饰?

    不然,为什么 跳转 哪个节点,回退到哪个节点,条件判断 都在 业务代码中 完成的 —— 和 流程设计器 的 设计,除了  N1,N2,N0,NX 有关系之外,基本没有啥 关系。

     

    我希望的工作流是怎样的:

    >首先一个 流程UI设计器,通过设计器 得到一个 流程XML 和 布局文件(反正也不参与后续,什么格式无所谓);

    >业务单据 填写信息,单击“保存”,执行:保存单据数据,一行代码 告诉 流程引擎:出库审批 的 O20131015001  单据,启动流程;

    >审批单据 填写意见,单击“审批”,执行:修改单据状态,一行代码  告诉 流程引擎:出库审批 的 O20131015001  单据,激发流程;

    >审批单据 填写意见,点击“驳回”,执行:修改单据状态,一行代码  告诉 流程引擎:出库审批 的 O20131015001  单据,激发流程;

    >于是,整个过程中:业务只需要 办完自己需要办的事情,然后通知 流程引擎 自己去分析流程 到了哪一步,自己分析下一步该怎么办;

     

    打个比方:

    1. 出库人员 填写一个 单据,单据拿给 秘书;

    2. 秘书拿给 经理,经理填写 同意;

    3. 秘书再拿给 老板,老板填写 同意/驳回;

     

    突发意外:老板 人间蒸发了;

    2. 秘书拿给 经理,经理填写 同意;

    于是下一个环节就是错误,这个错误的处理有两种:

    >秘书直接对经理说:老板没了,没有下一步审批人,您填写的单据无法流转,因为是同一个事务,您的“同意”也是无效的;您如果写 “不同意”,就不会有任何错误

    >秘书拿上经理同意的单据走了。然后她一分析:找不到老板;她不好擅自做主,于是给公司所有管理层 发了 一封邮件:老板不在,很多单据 无法审批,流程走不通

     

    秘书的处理方式,就像 我所看所想的 工作流引擎:

    >前者,因为老板没了,经理的 同意 成了一个错误;

    >后者,经理 直接就同意了——他不用管 下一步 该谁审批,也不用管 错误时 他该怎么做;

     

    这个比方中,秘书 就扮演了 流程引擎 的作用:她负责将单据 按照她 知道的流程 走下去;出现错误,他会按照 制度 通知指定的管理层;

     

    好的流程引擎,就像一个好的秘书(前面 老板蒸发,经理为难 的例子 可能不那么 严重,下面 的例子呢?);

    如果哪天,经理人间蒸发了,出库人员 单据写好了,客户拖着 货物 已经开车跑了;

    >前者,秘书告诉 出库人员:经理不在了,你的单据无法流转,因为是同一个事务,你的单据也是无效的;(单据可以填写失败,但是公司的货物可是已经 拖走了的)

    >后者,秘书收到 单据,她一分分析:找不到经理;她不好擅自做主,于是给公司所有管理层 发了 一封邮件:经理不在,很多单据 无法审批,流程走不通;

     

    流程引擎:只应该负责流程的传递,而不是 破坏 具体数据和决策。

     

    后期维护:

    哪天,老板娶了个 搞经融的 老婆;老板审批之后,老婆想查阅(不是审批)一下财务;

    业务代码 和 流程代码 混合的项目,除了修改 流程设计器 加节点 之外,还要 修改业务代码:N2节点,老板审批成功,则给老婆发一封邮件;

    而 业务代码 和 流程代码 分离的项目,流程设计器 中 增加一个 节点(执行插件,发送邮件,邮件接收人 从 XML 读取);

    程序结构图:

    最后的简洁:

    >不同类型的代码 分离,永远是 软件设计 的 潮流趋势:比方说 MVC框架,性能是比 WebForm 慢的,但是 因为实现了 代码分离,减少的是后期 维护成本;

    >流程引擎,只应该负责流程的传递,而不是因为流程的 错误 而 破坏 具体数据和决策;

    >作者 将会 以 本文思想,完成 自己心目中的 流程引擎,敬请关注(抽象程度将在  工作流之上,工作流 只是 流程引擎的 一个 分支插件);

     

     

  • 相关阅读:
    thinkphp自动映射分析
    thinkphp自动创建数据对象分析
    html模板输头部出现"&#65279"
    register_shutdown_function 函数详解
    mcrypt加密以及解密过程
    SVN不能解锁,报错:没有匹配的可用锁令牌的解决方法
    微信公众平台JSSDK开发
    PHP的UTF-8中文转拼音处理类
    PHP中文转拼音函数
    php生成mysql数据字典
  • 原文地址:https://www.cnblogs.com/shuxiaolong/p/20131015_001.html
Copyright © 2020-2023  润新知