您的位置:首页 > 其它

基于规则的业务流程分析

2008-07-05 22:59 489 查看
“思考得少,瞎干得多”,就是目前企业开发的现状。瞎干了两个月后,回头来分析一下一个有趣的流程,是我们目前项目中最复杂的一个流程(因为要完成它而不能动脑,所以复杂)。

首先把UML书上的案例扔到一边,那个是齐全的菜谱、佐料、原料而真实项目是荒地。想想走到荒地上给自己整一顿满汉全席,不容易啊…… 现在已经忘了最初听到这个流程的描述是怎么样的了。大概就是“一个待办项会发送和接收很多次,也可以发送接收一次,发送完后就不能再次发送了,最后一个接收结束后才能结束整个流程”——够昏的吧^O^遇到这种事千万不能听客户、需求人员甚至项目经理的,架构师才是设计这个系统的人,不能自己分析、定义业务对象,下课去吧。

第一反应就是发送和接收必须是两个不同的待办项,随后是必须定义两个不同的动作:完全发送和部分发送。概念一定要区分准确。 随后关于如何叫完全发送和部分发送有几次需求上的变化,但不影响流程的执行规则。

这个就形成了我在业务流程配置一文中写的ResponseTask类,当时的需求就是请求-接收,所以只写了两个Task;随后扩展成了每接收之后还有一个任务叫填写意见书,所有的意见书完成之后再开始一个新的任务。所以就改成了:请求-接收-响应三个操作,修改ResponseTask,增加了ResponseType这一枚举值属性,修改了结束的算法。目前的流程执行规则是相当死板的,完全硬编码在引擎内部,无法改变。以下是ResponseTask类和执行代码:

using System;

using System.Collections.Generic;

using System.Xml.Serialization;

namespace Microsoft.Applications.ChinaMobilePMS.FlowEngine

{

public class ResponseTask : TaskBase, IComparable<ResponseTask>

{

private int requestNumber = 0;

private ResponseType responseMode = ResponseType.Request;

[XmlAttribute("RequestNumber")]

public int RequestNumber

{

get { return requestNumber; }

set { requestNumber = value; }

}

[XmlAttribute("Mode")]

public ResponseType ResponseMode

{

get { return responseMode; }

set { responseMode = value; }

}

#region IComparable<ResponseTask> Members

public int CompareTo(ResponseTask other)

{

if (this.responseMode < other.responseMode) { return -1; }

else if (this.responseMode == other.responseMode) { return 0; }

else { return 1; }

}

#endregion

}

}

using System;

using System.Collections.Generic;

using System.Xml.Serialization;

namespace Microsoft.Applications.ChinaMobilePMS.FlowEngine

{

public class Activity : IActivity

{

//...

public void StartActivity(string actionValue)

{

switch (mode)

{

case TaskMode.Response:

{

responseTasks.Sort();

ResponseTask requestTask = responseTasks[0];

ResponseTask receiveTask = responseTasks[1];

ResponseTask responseTask = responseTasks[2];

if (status == StatusType.Scheduled)

{

status = StatusType.InProgress;

requestTask = responseTasks[0];

requestTask.CreateTask();

}

else if (status == StatusType.InProgress)

{

switch (actionValue)

{

case "CompleteSubmit":

requestTask.Approve += new ApproveHandler(receiveTask.CreateTask);

requestTask.ApproveTask();

receiveTask.RequestNumber++;

break;

case "Submit":

receiveTask.CreateTask();

receiveTask.RequestNumber++;

break;

case "Receive":

receiveTask.Approve += new ApproveHandler(responseTask.CreateTask);

receiveTask.ApproveTask();

receiveTask.RequestNumber--;

responseTask.RequestNumber++;

break;

case "Reject":

receiveTask.Reject += new RejectHandler(requestTask.CreateTask);

receiveTask.RejectTask();

receiveTask.RequestNumber--;

break;

case "Response":

responseTask.ApproveTask();

responseTask.RequestNumber--;

if (((requestTask.Status == StatusType.Completed) && (receiveTask.RequestNumber <= 0) && (responseTask.RequestNumber <= 0)))

{

CompleteActivity();

}

else

{

responseTask.Status = StatusType.InProgress;

}

break;

default:

break;

}

}

}

break;

}

}

}

}


昨天参考了Workflow Pattern,其实这个被我表达为Request-Receive-Response的流程的标准描述是以下两个的综合:
Parallel split pattern



Synchronization pattern



于是我拿出纸和笔,画下了这幅图:



想了想,这副图没有把完全发送与部分发送的分支表达出来,于是改成了这幅:


现在呢,有了选择。如果用户选择部分发送,它将走图一的流程,否则就一个简单的2-3-4走完。但是,这时依然缺少了东西,缺少了4开始的条件。并且,部分提交和完全提交唯一的区别就是是否结束1,所以不用专门配分支,再把选择和任务2视为并发任务,因为他们没有先后关系,虽然界面上操作有先有后,但这个选择不能决定任务2是否产生。又改:



这一个算是比较满意的分析模型。根据这个模型,先前硬编码的执行算法将被抽象为ControlRule,它将继承自RuleBase,代表了上图的流程线。而这个分支是用户在执行时选择的,暂定名为Choice:

<ControlRule Mode="Choice">

<Choice Result="Complete">

<Then />

</Choice>

<Choice Result="Partial">

<Then />

</Choice>

</ControlRule>

规则引擎将解释这个配置并执行。而在Task的执行上,也会定义在配置中,而不是现在这样硬编码。例,选择完全提交之后结束任务一:


<ControlRule Mode="Choice">

<Choice Result="Complete">

<Then>

<Task ID="1" Action="End" Mode="auto" />

</Then>

</Choice>

</ControlRule>


这里Mode="auto"意为系统自动处理,不需要产生待办项。接下来是关于任务2的产生,它与Choice并行关系的,而且是任务一提交后必然无条件产生的,故命名为Unconditional:

<ControlRule Mode="Choice" />

<ControlRule Mode="Unconditional">

<Task ID="2" Action="Start" Mode="manual" />

</ControlRule>


这里的Mode="manual"表示会生成一条待办项,到达指定办理人处。对于最后任务4启动的验证:

<ControlRule Mode="Conditional">

<Condition>

<Task ID="1" Status="Completed" />

<Task ID="2" Status="Completed" />

<Task ID="3" Status="Completed" />

</Condition>

<Then>

<Task ID="4" Action="Start" Mode="manual" />

</Then>

</ControlRule>


至此,已经基于规则实现了这个流程,其中的三条规则是:选择型、条件型、无条件型;进一步了解之后再进行补充。下一次,将围绕任务进行面向行为的分析,核心问题还是办理人的持久化目的地。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: