WF系列:顺序工作流和状态机工作流

来源:互联网 发布:博易大师分析软件 编辑:程序博客网 时间:2024/04/29 08:20

1 简介

  工作流实际上是对业务处理过程的建模,当我们设计工作流的时候,我们首先要分析业务处理过程中要经历的步骤。然后,我们就可以利用WF创建工作流模型来模拟业务的处理过程。

  我们知道,WF包含两种类型的工作流:顺序工作流和状态机工作流。顺序工作流提供了一系列有组织的步骤,一般情况下,步骤是逐一执行的。可能有的步骤需要等待某些事件的发生才可以继续执行,但通常情况下顺序工作流一般用于无需人工干预的操作。

  状态机工作流提供了一系列的状态。工作流从初始状态开始,到终止状态结束。两个状态之间定义行为进行过渡。通常情况下,状态机工作流对事件作出反应,事件的发生将会使状态发生改变。

  至于到底采用哪种类型的工作流取决于具体的业务管理过程。例如,你要建立一个工作流来模拟订单的处理过程。具体步骤如下:

  l     商店接受了订单,包括下单人、产品、数量等信息;

  l     商店检查客户是否拥有合法的信用卡。如果有,继续,否则结束;

  l     商店检查存货清单是否能够满足订单要求。如果有,继续,否则结束;

  l     商店要求信用卡公司支付合同金额。如果成功,继续,否则结束;

  l     将商品托运给客户。流程结束。

  从以上过程来看,采用顺序工作流就可以一气呵成。

  假如情况有如下变化:

  l     商店接受了订单,包括下单人、产品、数量等信息;

  l     商店检查客户是否拥有合法的信用卡。如果有,继续,否则结束;

  l     商店检查存货清单是否能够满足订单要求。如果有,继续,否则结束;

  l     如果产品有现货,产品货运公司托运产品;

  l     在托运之前,商店要求信用卡公司支付产品费用。如果成功,继续,否则结束;

  l     当产品托运后,处理流程等待客户确认已经收到。如果收到,流程结束。如果客户没有收到,流程将等待商品重新发送。在这时,商店和客户都可以取消订单,结束进程。

  这个流程和前一个流程的区别在于:有些过程需要暂时中止并等待其他过程的开始。这个中止过程一般情况下需要几天时间(网上购物大概3-5天)。

  状态机工作流的好处在于它可以定义状态,定义工作流如何从一个状态到另外一个状态。当外面的事件发生的时候,状态机工作流可以移动到不同的状态。外部行为可以是宿主程序引发工作流内部事件,也可以是宿主程序编程实现的下一个状态,也可以利用SetState Activity移动到下一个状态。

  2 创建状态机工作流

  具体参加原文,这里只介绍状态机工作流特有的几个活动:State activity, SetState activity, StateInitialization activity, StateFinalization activity。

  3 定义工作流状态

  拖拽三个State activity,分别设置为开始、工作、结束三个状态。

  4 状态过渡

  利用SetState activity,通过TargetStateName属性进行设置。

  5 在每个状态定义活动

  我们可以将四种活动添加到State Activity中:

  StateInitialization activity:只要它存在,则进入状态后,改活动第一个执行。StateInitialization activity是一个顺序化的活动,你可以将增加所有的活动,包括SetState activity。

  EventDriven activity:利用它可以控制外部事件,它也是一个顺序化的活动,可以将增加所有的活动,包括SetState activity。

  StateFinalization activity:离开状态最后执行的活动,它也是一个顺序化的活动,可以将增加所有的活动,包括SetState activity。

  State activity:State activity可以再嵌入State activity以形式具有等级结构的状态机工作流。这样,子状态活动可以继承父状态活动的driven behavior event。

  6 通讯服务

  对状态机工作流来说,典型的应用场景是工作流进入一个状态,然后等待宿主程序引发事件。通过EventDriven activity处理外部事件。你可以决定工作流执行的行为是什么,包括下一个要移动的状态。这里主要介绍两个活动:

  HandleExternalEventActivity:

  l     挂起当前流程,当外部触发事件时,流程继续向下运行

  l     引擎中要加载ExternalDataExchange服务

  l     ExternalDataExchange服务,要加载实绑定接口的类实现

  l     运行到HandleExternalEventActivity结点后,会进入idle状态,苏酲时间为9999-12-31

  l     只有当宿主中触发绑定的事件后才会继续向下运行。

  l     在实例挂起或没到HandleExternalEventActivity结点时,也可以在外部触发事件,这时当实例运行到该结点时HandleExternalEventActivity就可直接过去,而不用再触发了




CallExternalMethodActivity:

  l     在工作流内部调用外部方法

  l     引擎中要加载ExternalDataExchange服务

  l     ExternalDataExchange服务,要加载实绑定接口的类实现

  l     运行到CallExternalMethodActivity结点后自动调用实例中的方法。用参数映射中的设定传参,得到返回值



两个活动的说明:

双击代码全选
1
2
3
4
5
6
7
8
9
10
  [ExternalDataExchangeAttribute]
   public interface IOrderManagement
   {
    event EventHandler<OrderEventArgs> OrderShipped;
    event EventHandler<OrderEventArgs> OrderShippingCancel;
    event EventHandler<OrderEventArgs> OrderAcknowledged;
    event EventHandler<OrderEventArgs> OrderReShipping;
  
    bool InStock(string productID, int quantity);
}

  无论哪个活动,都必须有一个具有外部数据交换属性的接口。我个人反对在工作流代码中调用和业务逻辑相关的代码。所有和业务相关或数据库相关的代码都应该写在IOrderManagement的实现类中。HandleExternalEventActivity用于外部对工作流状态的调用,使工作流继续运行。CallExternalMethodActivity用于调用外部代码,以实现访问业务关心的代码,如判断库存是否满足要求,然后通过返回值决定工作流的运行路径。

  7 具体实现

  这里,我定义了四个状态,通过名称很容易知道每个状态的含义。



在开始状态,定义了一个调用外部方法活动,以检查数据库中的库存是否满足订单的要求,返回值为bool型,然后执行ifElse活动,以转向不同的状态。

  WaitingForShipping状态含有两个处理事件:一个是发送订单,一个是订单取消。下图是发送订单的状态图。


原创粉丝点击