[2]工作流的实现

来源:互联网 发布:如何让小米3用4g网络 编辑:程序博客网 时间:2024/06/04 17:43
首先再次说明一下我的想法:
  • 一个工作流是一串步骤的组合,每个步骤都可以看成是一个状态,状态的转移相当于流程的分支控制;状态内部实际上也是一个工作流,是整个工作流的一个子流;同时定义了依赖集Waits,允许该步骤等待前面几个工作的特定结果;定义了转向集Branches,表示该步骤取得某一结果,工作流中某些步骤可以开始执行。
  • 工作流中的每一个步骤都可以将步骤持久化或反持久化,可以进行权限控制。这是要逐步实现的功能。

根据 [1]几天狂想的成果:工作流的定义与模型  对工作流的描述:

WorkFlow :<&Step>
Step : <Steps , Branches , Waits>
Branch:<Result , Steps>
Wait:<Step,Result>
为了便于实现,进一步抽象出 Action作为一个动作,它执行一个动作并返回一个结果。一个步骤也是一个动作,但在动作的基础上多了前提条件等待和分支控制限制。
一、 下面给出了几个核心类型定义:

1.动作状态、参数和结果的定义
动作状态、参数和结果
2.分支定义
分支的定义
3.动作和步骤的定义
动作和步骤的定义

需要说明的是Action.Do()方法,它的实现者根据Param决定怎么执行一个动作,并返回一个结果。而Action的继承者Step的Do()方法,它除了根据Param,还要等待Waits中所有Step的结果,当它返回结果前,会适时引发StepTo事件以通知它的调用者下一步可以进行哪些Step的执行。实现以上接口,已经可以做工作流的开发了,一些取决于Do方法的实现。而IResult和IParam则是为了让Action能处理所有的类型。
举个例子说明IAction的灵活性:
    public partial class ActionForm : Form , JCLib.WorkFlow.IAction
    {
        Result _Result = null;
        public JCLib.WorkFlow.IResult Result{get{return _Result as JCLib.WorkFlow.IResult;}}
        Param _Param = null;
        public JCLib.WorkFlow.IParam Param { get { return _Param; } set { _Param = value as Param; } }
        public JCLib.WorkFlow.IResult Do()
        {
            this.ShowDialog();
            return _Result as JCLib.WorkFlow.IResult;
        }
   }

那么在这个窗体运行期间,可以做任意的事情,直到生成合适的Result,在关闭窗体后,结果也随之返回给调用者。调用者根据结果去判断应该做哪些后续的事情,对于Step也是一样道理,不同的是Do方法可能会判断它的先决条件是否成立,否则拒绝运行该窗体并返回一个空结果。

二、 为了方便,写了一些抽象类实现了接口中一些通用的操作,以减少实现者的代码量。

1.动作和步骤
动作和步骤
2.参数和结果
参数和结果
3.一个工具:Activator
一个工具:Activator

 这些抽象类没有什么特别的地方。
要注意的是Activator,它是一个工具类,且具有一系列的静态方法如Do,它可以根据传入的参数利用反射去执行一个Action或Step。这是令人激动一个亮点:可以动态加载指定的程序集并有选择地去执行里边的步骤或方法!
看一下下面的代码:
JCLib.WorkFlow.IResult result = JCLib.WorkFlow.Action.Do(typeof(ActionTest).Assembly, "JCLibTester.ActionForm");
MessageBox.Show(result.ResultCode + " " + result.ResultInfo);

它将一个动态执行一个Action,并将结果显示出来。
ActionTest是当前的窗体,而ActionForm也恰巧在当前运行的程序集里。如果目标类型不当前程序集中,则可以通过动态加载程序集的方法来加载。
原创粉丝点击