代码改变世界

MOSS多级审批工作流【StateMachine版】v1.1

2008-07-15 09:08 by Windie Chai, ... 阅读, ... 评论, 收藏, 编辑
去年我发布过一个MOSS多级审批工作流,采用顺序工作流模式开发后来又做了一些改进,用ConditionedActivityGroupActivity取代了繁复的WhileActivity+IfElseActivity嵌套,但仍然是顺序工作流
在第二篇文章的末尾我曾写道:“审批这样的流程并不适合用顺序工作流来实现,用WF的另外一种工作流-状态机工作流会更好”,为什么这样说呢?
我们已经知道,顺序工作流的执行过程是一个连续的步骤,从开始到结束,虽然我们可以利用While这样的循环活动让工作流看起来往回去执行了几步,但是这样的后果就是一张难以理解的流程图和复杂的执行逻辑。
真实世界的工作流程是灵活的,往往不是一条线走到底的,中间可能包含这许多决策,每个决策都可能让流程走向另外一个方向。所以包含人类参与的工作流其实是一个决策推动的流程,把它抽象到工作流中,就成了“事件驱动工作流”,也就是状态机工作流(StateMachine Workflow)。
状态机工作流由一系列状态(State)组成,每个状态中又可以包含一系列事件的处理程序。状态机工作流总是停留在一个状态中,等待必要的事件被触发,然后跳转到新的状态。
那么现在再来看看这个多级审批工作流的原始流程图:
 
下面是用状态机实现后的流程图:
 
你会发现,状态机工作流的流程图和我们最初的流程图相当接近,无论是流程块还是之间的连线。如果再和之前用顺序工作流实现后的流程图对比一下,那么以后你在遇到人类参与的工作流时,一定不会考虑用顺序工作流实现了。

下面简要的说明一下状态机工作流的开发要点:

1.如何规划状态?

在MOSS的状态机工作流中,我们一般这样规划一个状态:

在状态初始(StateInitializationActivity)时创建任务(CreateTaskActivity),在状态结束(StateFinalizationActivity)时删除任务(DeleteTaskActivity)。而在初始化和结束之间,我们可以添加多个事件驱动(EventDrivenActivity),EventDrivenActivity的作用是接收并处理事件(比如任务被修改的事件,OnTaskChangedActivity),然后可以根据事件的处理结果跳转到其它状态(SetStateActivity),你可以将SetStateActivity理解为各个状态之间的连接线。

2.如何实现Task3和Task4的并发?

注意在最初的流程图中,Task3和Task4是两个并列的任务,在这个审批流程的Sequence版实现中,我们当然选择用ParallelActivity来实现并发,在StateMachine中我们仍然可以这样做,不过如果要将Task3和Task4安排成两个状态,我们就得在ParallelActivity的两个分支中都添加一个SetStateActivity并指向相应的State。
但是这时候你会吃惊的发现,虽然每条分支都执行了,但只有最后一条分支中的SetStateActivity正确的执行了跳转。
因为一个EventDrivenActivity只能跳转到一个StateActivity,所以我们需要其它方法来实现Task3和Task4的并发。

我的方法是将Task3和Task4集成到一个状态里,先在状态初始时创建两个任务,然后添加两个几乎一模一样的EventDrivenActivity来分别处理两个任务被修改的事件,下面是这个EventDrivenActivity的子活动组成:

在处理完任务被修改的事件后,我会将此任务标记为“已完成”,并记录其审批结果;接着,利用IfElseActivity判断两个任务是否都被标记为“已完成”,如果还有任务没有完成,就不做任何操作,如果两个任务都已经完成,就再根据它们的审批结果来决定跳转到哪个状态。

3.为什么把删除任务的活动添加到了EventDrivenActivity内部而不是StateFinalizationActivity内部?

这样做是因为我想在任务被处理后马上删除它,但StateActivity总是等到执行SetStateActivity时才会执行到StateFinalizationActivity,而上面我们已经实现了两个任务都完成后才发生跳转,所以如果将DeleteTaskActivity添加到StateFinalizationActivity的话,就做不到实时删除任务了。 

4.为什么要在EventDrivenActivity内部添加IfElseActivity?

答案是为了实现直到两个任务都完成后才发生跳转。
但是,这样做的后果就是我不得不在每次处理完任务之后都添加这个IfElseActivity,好在我们的流程只有两个并发的任务,如果有三个、五个甚至更多呢?这种判断方法就显得非常麻烦,而且会让流程结构变得臃肿,难道就没有更好的方法吗?希望和大家一起探讨这个问题,我也会在下一篇文章中介绍一种取代这种频繁利用IfElseActivity进行判断的方法。

OK,以上就是这个多级审批工作流(StateMachine版)的实现要点,欢迎大家共同交流探讨。
源码下载:点击下载(Visual Studio 2008)