土制状态机在工作流引擎中的应用

/**
  * @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,以此类推。

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

未完待续 

时间: 2025-01-21 01:49:55

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

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

如果对工作流引擎没有了解过的同学可以先看前一篇文章: 土制状态机在工作流引擎中的应用http://ahuaxuan.iteye.com/blog/505124 /** * @author: ahuaxuan(张荣华) * @date: 2009-11-23 */ [size=medium] 在一个视频网站中,用户从上传一个视频,一直到视频能够正确的被其他用户下载观看,其中经历了一个很长的流程. 下面ahuaxuan来画一张图来表示这个简要的流程,但是实际上不同视频网站由于其架构的不同,可能也会导

工作流引擎的概念是什么?与WF中WorkflowRuntime(工作流运行时引擎)有什么关系吗?

问题描述 工作流引擎的概念是什么?与WF中WorkflowRuntime(工作流运行时引擎)有什么关系吗?工作流引擎包含哪些内容?帮忙介绍一些比较直观易于了解的资料,对于没接入过工作流引擎的人,有个形象的认识,明白什么是工作流?什么是工作流引擎?工作流引擎是平台级产品还是指的开发平台?K2.MyApps.osWorkflow等应该成为什么? 解决方案 解决方案二:http://baike.baidu.com/view/1636259.htm解决方案三:什么是工作流引擎(WorkflowEngin

动态业务工作流引擎Superflow研究概要

第一章 背景及目标 本人研究了多年的工作流引擎技术,作为研究成果的Superflow,已经有许多成熟的应用.我愿意把这些点滴的积累奉献出来,与大家共享作学问的乐趣与辛酸. 有人说,35岁一个程序员的暮年,我今年36了,才刚刚领悟到程序人生的真谛. §1-1 研制背景 企业的运作过程本质上是人.财.物等资源的优化和配置,形式上无一不体现为信息流.资金流.物流.价值流等合理的流动:随着社会分工的日益具体化,合作已成为主题,合作的体现形式必然是一个完整而高效的工作流程:有管理的企业的活动过程必然是有序

工作流引擎Activiti使用总结

1.简单介工作流引擎与Activiti 对于工作流引擎的解释请参考百度百科:工作流引擎 1.1 我与工作流引擎 在第一家公司工作的时候主要任务就是开发OA系统,当然基本都是有工作流的支持,不过当时使用的工作流引擎是公司一些牛人开发的(据说是用一个开源的引擎修改的),名称叫CoreFlow:功能相对Activiti来说比较弱,但是能满足日常的使用,当然也有不少的问题所以后来我们只能修改引擎的代码打补丁. 现在是我工作的第二家公司,因为要开发ERP.OA等系统需要使用工作流,在项目调研阶段我先搜索资

几种开源工作流引擎的简单比较(转)

摘要:目前开源工作流引擎用的最多的是jbpm , 各种特性都不错, 文档也比较多, 下面只简单列举一下 目前开源工作流引擎用的最多的是jbpm , 各种特性都不错, 文档也比较多, 下面只简单列举一下 其他几种工作流引擎的特性.   Apache ODE Enhydra Shark Bonita Open Business Engine Eclipse JWT  支持的流程建模标准  WS-BPEL 2.0,流程定义必须使用该标准编写才能执行 WfMC和OMG标准 符合WfMC规范 遵循WfMC

使用KNIME工作流引擎让数据分析变得更敏捷

在 developerWorks 文章 分析敏捷世界中的数据 中,我解释了数据分析变得敏捷需要满足的三个主要特征: 分析组件需要模块化,以便在许多不同的情形中使用它们. 要处理的数据需要看起来像一个矩形表,以便最大限度地降低组件之间的数据格式不兼容性. 各个分析组件需要能够利用极少的编程工作组合在一起,形成一个完整的分析. 工作流工具(比如用于数据挖掘.生物信息学和业务分析的工具)需要满足这些要求.与单个分析软件相比,实现数据分析的工作流引擎提供了许多优势. 运行一个工作流不是单个整体性的操作.

Activiti工作流引擎使用

Activiti 工作流引擎使用 1.简单介工作流引擎与Activiti 对于工作流引擎的解释请参考百度百科:工作流引擎 1.1 我与工作流引擎 在第一家公司工作的时候主要任务就是开发OA系统,当然基本都是有工作流的支持,不过当时使用的工作流引擎是公司一些牛人开发的(据说是用一个开源的引擎修改的),名称叫CoreFlow:功能相对Activiti来说比较弱,但是能满足日常的使用,当然也有不少的问题所以后来我们只能修改引擎的代码打补丁. 现在是我工作的第二家公司,因为要开发ERP.OA等系统需要使

.Net 三款工作流引擎比较:WWF、netBPM 和 ccflow

原文:.Net 三款工作流引擎比较:WWF.netBPM 和 ccflow 下面将对目前比较主流的三款工作流进行介绍和比较,然后通过三款流程引擎分别设计一个较典型的流程来给大家分别演示这三款创建流程的过程.这三款工作流程引擎分别是 Windows Workflow Foundation,NetBPM, CCFlow. NetBPM 与 CCFlow 是两款国内知名的开源软件,尤其是ccflow在国内的发展势头强劲. 这个典型的流程假设:公司有两级领导,一级为主管Chief,一级为老板Boss 场

Lotus工作流引擎 - Simpleflow Express CS版 Release

问题描述 Lotus工作流引擎产品-业务流程,自主实施Simpleflow又推出新版本了SimpleflowExpressCS版与Simpleflow标准版的区别在于1.流程定义与应用库合二为一更方便用户的维护与管理同时也支持标准版的分布式的流程定义配置2.支持CS模式简化了设计元素,去除了针对BS的设计元素,使设计更简洁,用户更容易上手3.美化了UI界面SimpleFlow不再是只注重功能,而忽略UI的产品了.4.增加了[流程应用表]主表单,作为流程表单样例用户可以直接使用此表单,或者拷贝后直