/**
  * @author : ahuaxuan
  * @date 2009-10-27
  */

很早之前(应该是一年以前),ahuaxuan在用dfa实现文字过滤一文中使用确定有限自动机实现了词典的高速查询。其实在当时那段时间里,由于对状态机有了一定的研究,ahuaxuan也触类旁通的理解了工作流引擎的核心体制。于是当时就用python写了一个小巧的工作流引擎的示例,在这之前ahuaxuan没有看过任何工作流引擎的实现,该实现纯属思维的自我延伸。

现在我来说说我的实现。
状态机的本质是状态的迁移,即从A状态+某个动作===》B状态。到这里我们还要来看看这张图。

从这张图中我们可以看到,状态(大写字母)+动作(小写字母)可以到达新的状态。那么对于程序员来说,我们要做的就是将这种机制用程序表达出来。比如说我们最常想到的是什么?矩阵!

这很好理解,但是对于工作流引擎来说,由于状态的迁移涉及到:当前状态+动作+条件===》新状态。
所以用二维的矩阵无法表示出这种逻辑。那么我们可以将矩阵中的元素替换为条件数组。
这样,我们可以通过当前状态+动作得到一个条件数组,然后再遍历这个条件数组,条件数组中的元素即是条件和满足条件的下一个状态(虽然本质上是一个三维数组,但是在这里还是看成矩阵+数组元素比较符合逻辑)。

这里需要画一个图,一个矩阵,矩阵中的元素是一个条件数组

没错,这是一种方案,但是这里有一个问题,那就是每次做状态迁移的时候,我们必须知道某个状态在矩阵一维上的index,已经某个动作在矩阵二维上的index.有了这两个index我们才能得到条件数组。所以这里还有一个繁琐的转换操作操作。来看一段伪代码:

1.conditions = matrix[getStatusIndex[‘A’], getActionIndex[‘a’]]
2.For condiction in conditions:
3.       If condition match input:
4.              Return Condition.nextStatus

核心流程大概就是这样,当

那么除了矩阵这种数据结构,我们还有其他的数据结构可以用来表示: “当前状态+动作+条件===》新状态”吗。

当然有,那就是使用树结构。在了解了三维数组的实现之后,再来看树实现,应该和容易了,那就直接上图, 将上图的矩阵转换成树结构之后,我们可以得到如下的树结构。

那现在我们来审视一下现在的问题,打个比方,我们现在手里有两张牌,一张是状态A,一张是动作a,我们如何通过这两种牌来得到条件集合呢,最简单的方法是首先遍历第二层节点,找到A,然后再遍历A的子节点,找到a。通过两次for循环找到了条件集合,而条件集合中包含着下一个状态。

那么有没有更简单更快速的方式可以直接找到条件集合,而直接跳过两次遍历呢。有,ahuaxuan的想法是tree+hash.也就是通过A的hash值,我们可以直接找到tree上的A节点。然后再通过a的hash值,我们可以直接找到A的子中的a节点。得到a节点之后我们就可以条件集合。那么我们可以用什么样的数据结构来实现一个这样的模型呢。这里面有hash运算,那么我们首先选择HashMap来创建这么一颗树。

我们来看一下这个定义:

Map<String, Map<String, Map<String, List<Transition>>>> dfa。  

那么我们如何根据A,和a来得到一个条件集合呢?

Dfa.get[“processName”].get[“A”].get[“a”]  

通过这样的方式,我们就可以根据当前状态和当前的动作得到一个条件集合。然后遍历这个条件集合就是找到满足“输入“的条件,该条件会指向下一个状态。

我们来看一下代码实现:
首先我们来构造这么一个状态机:

1.private void constructDfa(List<WfProcess> processList) {
2.        for (WfProcess pro : processList) {
3.            Map<String, Map<String, List<Transition>>> pmap = new HashMap<String, Map<String,List<Transition>>>();
4.            dfa.put(pro.getName(), pmap);
5.
6.            for (State sta : pro.getStates()) {
7.                Map<String, List<Transition>> smap = new HashMap<String, List<Transition>>();
8.                pmap.put(String.valueOf(sta.getName()), smap);
9.
10.                for (Action action : sta.getActions()) {
11.                    List<Transition> transitions = new ArrayList<Transition>();
12.                    for (String transName : action.getTransNames()) {
13.                        transitions.add(pro.getTransitions().get(transName));
14.                    }
15.
16.                    smap.put(String.valueOf(action.getName()), transitions);
17.                }
18.
19.            }
20.        }
21.    }  

接着我们来看看如何根据这个状态机来做状态迁移:

1.public String getNextState(String processName, String stateId, String actionId, Map<String, String> conditions) {
2.
3.        List<Transition> transitions = dfa.get(processName).get(String.valueOf(stateId)).get(String.valueOf(actionId));
4.
5.        for (Transition trans : transitions) {
6.            if (match(trans.getConditions(), conditions)) {
7.                return trans.getToState();
8.            }
9.        }
10.
11.        StringBuilder sb = new StringBuilder();
12.        sb.append("There is no state for process : ").append(processName);
13.        sb.append(", stateId : ").append(stateId);
14.        sb.append(", actionId : ").append(actionId);
15.        sb.append(", conditions : ").append(conditions);
16.
17.        throw new WorkFlowStateException(sb.toString());
18.    }  

通过这种tree + hash的方式,我们可以很容易的进行状态的迁移,不需要那么多for循环。但是for循环确实有这样的实现。

今天早上下载了osworkflow的代码,稍微看了一下AbstractWorkflow的doAction方法。
发现osworkflow就是通过循环来实现状态的迁移的,比如说上图中树结构的状态可以用以下伪代码:

1.For state in states:
2.    If state.name == inputStateName:
3.        For action in state.actions:
4.            If action.name == inputActionName:
5.                    for transition in action.transitions:
6.    …………………………………………………………………

通过这种方式,用户传入inputStateName和inputActionName, osworkflow得到了一组transition,并根据条件选择某个transition, 这样也实现了状态的转移。

从这里面可以看出,osworkflow是利用广度优先的原则,先找到符合条件的state,然后再找到符合条件的action,以此类推。

说到这里,通过这种状态机实现工作流引擎的方式基本的完全的,较为清晰的呈现在我们眼前了。

未完待续

土制状态机在工作流引擎中的应用相关推荐

  1. 工作流引擎在视频网站架构中的应用

    如果对工作流引擎没有了解过的同学可以先看前一篇文章: 土制状态机在工作流引擎中的应用 http://ahuaxuan.iteye.com/blog/505124 /** * @author: ahua ...

  2. 浅谈工作流引擎的几个关键因素

    工作流引擎的定义已经众所周知,可是解释却五花八门的,想想这也正常,因为用于状态机的工作流引擎和业务工作流引擎分析模式本身就有很大的不同.业务工作流基于不同文化解释也不同. 状态机工作流适用于根据各种状 ...

  3. 谈谈BPM工作流引擎

    BPM.工作流与OA BPM与工作流.OA其实是不同的概念.但笔者发现很多人依然会把三者混为一谈.虽说,企业管理相关理念发展到如今,BPM与工作流已经融合为一了,但还是可以了解三者的区别. 工作流基本 ...

  4. 如何优雅的设计工作流引擎(荣耀典藏版)

    目录 前言 一.业务应用场景 二.工作流介绍 2.1 定义 2.2 工作流参考模型 2.3 工作流引擎特性 2.3 工作流引擎特性 2.5 工作流引擎和状态机的差异 三.开源工作流引擎 3.1.Act ...

  5. 可自管理的分布式工作流引擎的设计与实现

    <script type="text/javascript"></script> <script src="http://pagead2.g ...

  6. 工作流系列之可自管理的分布式工作流引擎的设计与实现

    这篇文章是偶在清华读研究生时发表在国家核心期刊CIMS("Design and implementation of self-managed distributed workflow eng ...

  7. 工作流引擎核心设计思路!

    作者:vivo 互联网服务器团队- Cheng Wangrong 一.业务背景 营销自动化平台可以支持不同用户生命周期的活动旅程策略配置 ,根据用户触发的不同活动行为,进行差异化的营销触达方案.同时各 ...

  8. Java三大主流开源工作流引擎技术分析

    首先,这个评论是我从网上,书中,搜索和整理出来的,也许有技术点上的错误点,也许理解没那么深入.但是我是秉着学习的态度加以评论,学习,希望对大家有用,进入正题! 三大主流工作流引擎:Shark,oswo ...

  9. 三大主流开源工作流引擎技术分析与市场预测

    1.从<功夫>说起 时下的新新人类看到我,一定会认为在下是个十足的老古董,这不,<功夫>这样的片子我到今年2月底才看.不过看过<功夫>,我想的一定比一般的人多:周星 ...

  10. 工作流引擎-协作模式-最后一个人发送选择到达节点与接受人的场景设计与实现...

    工作流引擎中协作模式下最后一个人发送选择到达节点与接受人的场景 设计与实现 1.1:  关键字 驰骋BPM, CCFlow,JFlow,协作模式 1.2:  所需要的知识点 多人处理规则,协作模式,节 ...

最新文章

  1. lua的table+setfenv+setmetatable陷阱
  2. UVA-10054 The Necklace (欧拉回路)
  3. OpenCV高级拼接Stitcher类
  4. C 语言实现数组冒泡排序
  5. Linux系统openssl测试指导,Linux管理员必用:OpenSSL服务器测试技巧
  6. TensorFlow和ML前5名的课程
  7. 【AIX 命令学习】lsattr 显示一个给定设备或一种设备的属性
  8. 阿里云500服务器内部错误,腾讯云服务器网站不能打开 提示内部错误http 500
  9. 定时器和promise_从Promise链理解EventLoop
  10. SpringCloud学习笔记029---在SpringCloud项目中使用Zuul实现基本的网关统一处理
  11. 互联网岗位介绍和成长
  12. 【论文笔记】Learning Deep Face Representation
  13. C语言课设:图书管理系统
  14. NSGA2 算法MATLAB完整代码 中文注释详解
  15. Android 开 发 资 源 分 享
  16. 计算机实习生听课记录,舞蹈课实习听课记录
  17. 白帽黑客必备的网络安全基础问答
  18. AD7606分析讲解
  19. 前端导出表格,万级数据,带样式(留自用)
  20. PS教程:--虚线教程大全

热门文章

  1. atitit.提升性能AppCache
  2. Atitit.ui控件---下拉菜单选择控件的实现select html
  3. paip.提升用户体验---c++ qt 悬浮窗实现
  4. Julia: LaTeX 符号
  5. (转)这是券商对金融科技最看重的一年!
  6. 【数据预测】基于matlab斑点鬣狗算法优化BP神经网络数据预测【含Matlab 219期】
  7. 【优化预测】基于matlab粒子群算法优化DBN预测【含Matlab源码 1420期】
  8. 【定位问题】基于matlab三维chan算法求解室内定位问题【含Matlab源码 580期】
  9. 【脑电信号】基于matlab小波变换脑电信号特征提取【含Matlab源码 511期】
  10. 【元胞自动机】基于matlab元胞自动机模拟小区车流量【含Matlab源码 358期】