.Net三款⼯作流引擎⽐较:WWF、netBPM和ccflow
下⾯将对⽬前⽐较主流的三款⼯作流进⾏介绍和⽐较,然后通过三款流程引擎分别设计⼀个较典型的流程来给⼤家分别演⽰这三款创建流程的过程.这三款⼯作流程引擎分别是 Windows Workflow Foundation,NetBPM, CCFlow.
NetBPM 与 CCFlow 是两款国内知名的开源软件,尤其是ccflow在国内的发展势头强劲。
这个典型的流程假设:公司有两级领导,⼀级为主管Chief,⼀级为⽼板Boss
场景描述:
在某公司中,部门员⼯休假需要主管Chief的批准。
如果休假天数⼤于10天,则在部门主管同意后,还必须⽼板Boss批准。
咏柳贺知章如果是部门主管请假则直接提交⽼板批准。
在休假被批准之前,申请⼈可以撤销休假申请。
申请批准后,对休假天数进⾏修改(也可以是其他业务数据处理)。每次休假申请结束之后,不管通过
未通过或是否取消,都必须记录下来。
流程结束时,系统要把请假的结果信息Email给申请⼈。
对于⼤于10天的申请,如果部门主管已批准同意⽽上级主管还未批准,这时申请⼈撤销申请后,系统应发Email通知部门主管申请已撤销。我们这⾥只是⼀个模拟,当然现实⽣活中情况⽐这个更加复杂⼀些;
Windows Workflow Foundation
微软的⼯作流产品,提供⼀套⼯作流引擎和VS解决⽅案⾃带的流程设计器,但是该流程设计器⾯对的是程序员⽽⾮业务⼈员,所以界⾯⽐较专业,流程运⾏只能创建控制台应⽤程序,没有流程运⾏界⾯,没有表单库,如需要表单和界⾯需要⼆次开发。
使⽤WWF创建流程:
1. 启动VS2010,创建⼀个顺序⼯作流控制台的程序。
2. 输⼊项⽬名称,点击确定,将⾃动进⼊流程设计界⾯。
3. ⾃动⽣成的Workflow1.cs是⼀个⼯作流组件。小手拉大手手抄报
4. ⼯具箱中拖放⼀个IfEl活动组件到设计界⾯上。
5. 此时就需要较多的编码⼯作和表单界⾯设计⼯作,如在idelBranchActivitiy1左侧分⽀,⽤以判断请假⼈是否新申请请假还是取消请假,激活Conditiong属性,并且添加内部事件EvaluateQingJiaNoValidCode,并激活,在内部输⼊逻辑代码根据数据库记录判断请假是否通过,未通过则取消请假。也可以⾛另⼀分⽀EvaluateQingJiaCode继续申请新的请假;
6. 拖放parallelActivity1组件在IfEl节点后,⽤以判断请假⼈是否为Chief,设置quenceActivity1中的codeActivity3属性的ExecuteCode处理程序为EvaluateChiefNoValidCode,并激活,内部代码⽤以判断不是Chief的情况,另⼀分⽀quenceActivity1中则判断是Chief的情况;
7.如果不是Chief请假,则需要在EvaluateChiefNoValidCode中进⾏逻辑判断和表单的设计,填写请假申请单,并拖放IfEl组件,实现其中的codeActivity6代码⽤以判断⼤于10天的情况。
8.F5即可运⾏控制台程序,其中的通过未通过或是否取消的数据需要记录,需要通过代码和设计数据库来实现,发送Email也需要代码实现,WWF没有提供该功能。
WWF下设计的流程图如下:
NetBPM供的多音字
从JBpm1移植到平台下的开源⼯作流项⽬,⼆次开发有⼀定的难度,因为其使⽤的Castle框架有很多⼦项⽬,技术点较多,需要⼀⼀熟悉后才能进⾏流程的⼆次开发。
使⽤NetBPM创建⼯作流过程:
椒盐虾菇
1. 使⽤NetBPM的难点之⼀是要理解⽣成配置⽂件,提交请假单配置如下:
<?xml version="1.0"?>
<!-- NOTE:在定义流程时,建议先画出流程图,然后再来定义,这样思维清晰,也不易于出错
关于l如何定义,请严格按照nPdl规定 -->
<process-definition>
<!-- =================================== -->
<!-- == PROCESS DEFINITION PROPERTIES == -->
<!-- =================================== -->
<name>请假DEMO</name>
<description>该流程模拟公司的请假流程, </description>
<responsible>ae</responsible>
<!-- ====================== -->
<!-- == START & ENDSTATE == -->
<!-- ====================== -->
<start-state name="start leave request">
<description>提交请假单</description>
<!-- 定义了role,引擎在该start-state节点执⾏时,就会把执⾏者信息赋值给⾓⾊对应的属性“requester” -->
<role>requester</role>
<!-- 在这⾥定义start-state的field,它表⽰该filed相关联的属性,并且在该state,它对属性的访问权利。
如果需要定义其在web表单上的操作界⾯,如何进⾏web表单显⽰等,需要在l⽂件对应节点补充该field -->
赠从弟其一<field attribute="start date" access="write-only-required"/>
<field attribute="end date" access="write-only-required"/>
<field attribute="leave days" access="write-only-required"/>
<field attribute="comment" access="write-only"/>
<transition to="Is Cancel Fork"/>
</start-state>
<!-- 结束节点除名称外不要定义其他-->
<end-state name="end"/>
<!-- ====================== -->
<!-- == Actions == -->
<!-- ====================== -->
<!-- 解释:这⾥定义process-definition节点的action,有效的事件类型为:process-instance-start, process-instance-end and process-instance-cancel -->
第一台电视机
<!-- 此处具体为:在流程结束的时候, 发送E-Mail消息给申请者,记录请假⽇志 -->
<action event="process-instance-end"
handler="NetBpm.Example.LeaveOfAbnce.EmailAction, NetBpm.Example.LeaveOfAbnce" on-exception="log">
<!--定义action参数,供委托类实例化类调⽤⽅法时获取使⽤。如这⾥的EmailAction的run⽅法发送邮件,需要知道发给谁,邮件标题等等,那么
参数可以提供辅助-->
<parameter name="to">previousActor</parameter>
<parameter name="subject">您提交了请假申请</parameter>
<parameter name="message">you requested a holiday from ${start date} to ${end date} with comment ${comment}</parameter>
</action>
<!-- 此处具体为:在流程结束的时候记录请假⽇志, 此处Log模拟注意:每个节点可以定义多个action -->
<action event="process-instance-end"
handler="NetBpm.Example.LeaveOfAbnce.LogLeaveInfoAction, NetBpm.Example.LeaveOfAbnce" on-exception="log">
<parameter name="LogInfo">记录请假⽇志? :) </parameter>
</action>
<!-- ================ -->
<!-- == ATTRIBUTES == -->
<!-- ================ -->
<!-- 解释:定义属性值及其序列化⽅式。属性值⼀般包括3类 -->
<!-- one:⾓⾊对应的属性 -->
<attribute name="requester" type="actor"/>
<attribute name="chief" type="actor"/>
食雕
<attribute name="boss" type="actor"/>
<!-- two:所有acitivity-state(包括start-state)处需要更新的属性,和⽤户表单内容对应 -->
<attribute name="start date" type="date"/>
<attribute name="end date" type="date"/>
<attribute name="leave days" type="integer"/>
<attribute name="comment" type="text" initial-value="请假理由或者备注"/>
<attribute name="Chief evaluation result" type="evaluation"/>
<attribute name="Boss evaluation result" type="evaluation"/>
</concurrent-block>
</process-definition>
2. 其它配置⽂件代码太长就不⼀⼀贴出来;
3. 定义委托类:委托类包含在lib⽂件夹下的程序集中。
因为委托类数⽬众多,这⾥仅贴出⼏个典型的委托类:
1. NetBpm.Example.LeaveOfAbnce.AutoSetAttributionsAction:该委托类设计为⼀个通⽤委托类,这⾥⽤来设置表识属性,如流程经过⽤户取消请假路径,则把RunTrace属性设置为requestercancel,供WhichWayDicision作判断⽤。奔的多音字
2. NetBpm.Example.LeaveOfAbnce.AnyOneJoin: 该委托主要⽤来设置激活⽗flow机制,这⾥是只要任何⼀条路径到达了join,则激活⽗flow,流程往下流。
3. NetBpm.Example.LeaveOfAbnce.WhichWayDecision:该委托根据流程实际流过路径,根据标识属性RunTrace等进⾏⾛哪条边的抉择。
4. 本⽂仅仅是⼀个⽰例,给⼤家提供⼀个运⽤nPdl定义NetBPM流程的参考,如果要把该流程投⼊现实中使⽤显然还需要做很多优化。其中的代码量还是很⼤的。
NetBPM下设计的流程图如下:
CC Flow
ccflow是⼀款国产开源⼯作流。⽀持SQLServer、Oracle、Access、MySQL数据库,⽀持群集计算、⽀持多国语⾔。流程设计、表单设计都是可视化的,所见即所得。 ccflow提供了强⼤的数据分析功能:流程运⾏的各种报表、图形、挖掘、赚取,可以对实(时)效性、成本分析(⼈⼒、时间、财物),进⾏全⽅位的分析、监控。 Ccflow更可与⼿机+⼿机短信+短信猫+电⼦邮件⽆缝连接,让您的⼯作第⼀时间沟通,第⼀时间处理。
使⽤CC Flow创建⼯作流过程:
1. 在web容器中安装好程序后,打开流程设计器,建⽴请假流程,即可⽣成填写请假单和结束节点;
2. 拖动Chief审批节点、 Boss审批节点,添加连线以及标签注明;
3. 设置表单:邮件选择傻⽠型表单或者⾃由类型表单,设置表单后,设置每个节点的⼯作岗位;
4. 设置流程跳转⽅向条件,如判断情⼈是谁,判断请假天数等,选择的数据来源⾃表单数据。
5. 点击运⾏即可运⾏流程;可打开windows rvice,即可使⽤⾃带的消息提醒以及邮件发送功能;
CC Flow设计的流程图如下:
综上所述,三款的⼯作流区别如下表: