基于规则的业务流程分析
2008-07-05 22:59
489 查看
“思考得少,瞎干得多”,就是目前企业开发的现状。瞎干了两个月后,回头来分析一下一个有趣的流程,是我们目前项目中最复杂的一个流程(因为要完成它而不能动脑,所以复杂)。
首先把UML书上的案例扔到一边,那个是齐全的菜谱、佐料、原料而真实项目是荒地。想想走到荒地上给自己整一顿满汉全席,不容易啊…… 现在已经忘了最初听到这个流程的描述是怎么样的了。大概就是“一个待办项会发送和接收很多次,也可以发送接收一次,发送完后就不能再次发送了,最后一个接收结束后才能结束整个流程”——够昏的吧^O^遇到这种事千万不能听客户、需求人员甚至项目经理的,架构师才是设计这个系统的人,不能自己分析、定义业务对象,下课去吧。
第一反应就是发送和接收必须是两个不同的待办项,随后是必须定义两个不同的动作:完全发送和部分发送。概念一定要区分准确。 随后关于如何叫完全发送和部分发送有几次需求上的变化,但不影响流程的执行规则。
这个就形成了我在业务流程配置一文中写的ResponseTask类,当时的需求就是请求-接收,所以只写了两个Task;随后扩展成了每接收之后还有一个任务叫填写意见书,所有的意见书完成之后再开始一个新的任务。所以就改成了:请求-接收-响应三个操作,修改ResponseTask,增加了ResponseType这一枚举值属性,修改了结束的算法。目前的流程执行规则是相当死板的,完全硬编码在引擎内部,无法改变。以下是ResponseTask类和执行代码:
昨天参考了Workflow Pattern,其实这个被我表达为Request-Receive-Response的流程的标准描述是以下两个的综合:
Parallel split pattern
Synchronization pattern
于是我拿出纸和笔,画下了这幅图:
想了想,这副图没有把完全发送与部分发送的分支表达出来,于是改成了这幅:
现在呢,有了选择。如果用户选择部分发送,它将走图一的流程,否则就一个简单的2-3-4走完。但是,这时依然缺少了东西,缺少了4开始的条件。并且,部分提交和完全提交唯一的区别就是是否结束1,所以不用专门配分支,再把选择和任务2视为并发任务,因为他们没有先后关系,虽然界面上操作有先有后,但这个选择不能决定任务2是否产生。又改:
这一个算是比较满意的分析模型。根据这个模型,先前硬编码的执行算法将被抽象为ControlRule,它将继承自RuleBase,代表了上图的流程线。而这个分支是用户在执行时选择的,暂定名为Choice:
这里Mode="auto"意为系统自动处理,不需要产生待办项。接下来是关于任务2的产生,它与Choice并行关系的,而且是任务一提交后必然无条件产生的,故命名为Unconditional:
这里的Mode="manual"表示会生成一条待办项,到达指定办理人处。对于最后任务4启动的验证:
至此,已经基于规则实现了这个流程,其中的三条规则是:选择型、条件型、无条件型;进一步了解之后再进行补充。下一次,将围绕任务进行面向行为的分析,核心问题还是办理人的持久化目的地。
首先把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>
至此,已经基于规则实现了这个流程,其中的三条规则是:选择型、条件型、无条件型;进一步了解之后再进行补充。下一次,将围绕任务进行面向行为的分析,核心问题还是办理人的持久化目的地。
相关文章推荐
- 企业基于管理软件SOA的业务流程分析
- Activity启动流程分析(基于android 5.1)
- 一个基于WF的业务流程平台
- 分享 基于IT环境下风险管理导向型企业业务流程的特征
- Android系统从加电到Home桌面出现流程分析(基于Android-2.3)
- 业务流程分析和建模 推荐
- 基于WF设计业务流程平台_特定群体与特定人
- 基于Linux与Busybox的Reboot命令流程分析
- [置顶] 基于稀疏表示的多目标跟踪基本流程(文献分析)
- 基于ar9331 mips架构AP121 uboot分析(4) 启动流程 Stage1
- 基于事件驱动的领域模型实现框架 - 分析框架如何解决各种典型业务逻辑场景
- 分析基于Jsp+Servlet+JavaBean的个人信息管理系统的运行流程
- keystone业务流程的代码分析(一)
- 业务审批过程分析与使用Sbo系统存储过程实现业务审批流程状态检索
- 网站项目模型及业务流程分析
- 根据业务规则分析业务对象,然后生成表结构
- 基于地图的工作流设计器,及基于地图的业务流程办理界面(一)
- 基于N源码的ContentProvider调用流程分析
- 堂食快餐连锁店系统(一)业务流程分析
- Android基于源码分析AsyncTask的工作流程