zoukankan      html  css  js  c++  java
  • NetBpm 示例:请假审批(6)

    转载注明出处: http://www.cnblogs.com/anbylau2130/p/3877983.html

    原文: 请假示例



    流程定义包源码下载(注:par包就是zip格式压缩包)。原文地址:http://www.cnblogs.com/LuBen/archive/2007/08/11/852010.html(转载请保留) 请假流程描述 流程图: 假设:公司有两级领导,一级为主管(Chief),一级为老板(Boss),我们这里只是一个模拟,当然现实生活中情况比这个更加复杂;-) 描述: 在某公司中,部门员工休假需要主管(Chief)的批准。 如果休假天数大于10天,则 在部门主管同意后,还必须老板(Boss)批准。 如果是部门主管请假则直接提交老板批准。 在休假被批准之前,申请人可以撤销休假申请。 申请批准后,对休假天数进行修改(也可以是其他业务数据处理)。 每次休假申请结束之后,不管通过未通过或是否取消,都必须记录下来。 流程结束时,系统要把请假的结果信息Email给申请人。 对于大于10天的申请,如果部门主管已批准同意而上级主管还未批准,这时申请人撤销申请后,系统应发Email通知部门主管申请已撤销。 流程定义之processdefinition.xml 1
    <?xml version="1.0"?> 2<!-- NOTE:在定义流程时,建议先画出流程图,然后再来定义,这样思维清晰,也不易于出错 3 关于processdefiniton.xml如何定义,请严格按照nPdl规定 --> 4<process-definition> 5 6 <!-- =================================== --> 7 <!-- == PROCESS DEFINITION PROPERTIES == --> 8 <!-- =================================== --> 9 <name>请假DEMO</name> 10 <description>该流程模拟公司的请假流程, Made By LuBen</description> 11 <responsible>ae</responsible> 12 13 <!-- ====================== --> 14 <!-- == START & ENDSTATE == --> 15 <!-- ====================== --> 16 <start-state name="start leave request"> 17 <description>提交请假单</description> 18 <!-- 定义了role,引擎在该start-state节点执行时,就会把执行者信息赋值给角色对应的属性“requester” --> 19 <role>requester</role> 20 <!-- 在这里定义start-state的field,它表示该filed相关联的属性,并且在该state,它对属性的访问权利。 21 如果需要定义其在web表单上的操作界面,如何进行web表单显示等,需要在webinterface.xml文件对应节点补充该field --> 22 <field attribute="start date" access="write-only-required" /> 23 <field attribute="end date" access="write-only-required" /> 24 <field attribute="leave days" access="write-only-required" /> 25 <field attribute="comment" access="write-only" /> 26 <transition to="Is Cancel Fork" /> 27 </start-state> 28 29 <!-- 结束节点除名称外不要定义其他--> 30 <end-state name="end" /> 31 32 33 <!-- ====================== --> 34 <!-- == Actions == --> 35 <!-- ====================== --> 36 <!-- 解释:这里定义process-definition节点的action,有效的事件类型为:process-instance-start, process-instance-end and process-instance-cancel --> 37 38 <!-- 此处具体为:在流程结束的时候, 发送E-Mail消息给申请者,记录请假日志 --> 39 <action event="process-instance-end" 40 handler="NetBpm.Example.LeaveOfAbsence.EmailAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 41 <!--定义action参数,供委托类实例化类调用方法时获取使用。如这里的EmailAction的run方法发送邮件,需要知道发给谁,邮件标题等等,那么 42 参数可以提供辅助--> 43 <parameter name="to">previousActor</parameter> 44 <parameter name="subject">您提交了请假申请</parameter> 45 <parameter name="message">you requested a holiday from ${start date} to ${end date} with comment ${comment}</parameter> 46 </action> 47 <!-- 此处具体为:在流程结束的时候记录请假日志, 此处Log模拟 注意:每个节点可以定义多个action --> 48 <action event="process-instance-end" 49 handler="NetBpm.Example.LeaveOfAbsence.LogLeaveInfoAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 50 <parameter name="LogInfo">记录请假日志? :) </parameter> 51 </action> 52 53 <!-- ================ --> 54 <!-- == ATTRIBUTES == --> 55 <!-- ================ --> 56 <!-- 解释:定义属性值及其序列化方式。属性值一般包括3类 --> 57 <!-- one:角色对应的属性 --> 58 <attribute name="requester" type="actor" /> 59 <attribute name="chief" type="actor" /> 60 <attribute name="boss" type="actor" /> 61 62 <!-- two:所有acitivity-state(包括start-state)处需要更新的属性,和用户表单内容对应 --> 63 <attribute name="start date" type="date" /> 64 <attribute name="end date" type="date" /> 65 <attribute name="leave days" type="integer" /> 66 <attribute name="comment" type="text" initial-value="请假理由或者备注" /> 67 <attribute name="Chief evaluation result" type="evaluation" /> 68 <attribute name="Boss evaluation result" type="evaluation" /> 69 70 <!-- three:标识属性,该属性不会在web界面上体现,主来用来存储流程标识信息,供后面的逻辑处理使用 --> 71 <!-- 该属性不会在界面上呈现, 在具体流程路径中被设置以决定Decide Which Action如何走 --> 72 <attribute name="RunTrace" type="text" /> 73 <!-- 该属性不会在界面上呈现, 该属性被用来设置流程结束将要发送给用户的邮件信息(邮件标题, 如果需要邮件内容可扩展) --> 74 <attribute name="ToUserEmailSubject" type="text" /> 75 76 <!-- =========== --> 77 <!-- == NODES == --> 78 <!-- =========== --> 79 <!-- 定义流程包含的所有节点 --> 80 81 <!-- 定义decision节点, 从decision可以流出多条边(transition),这些边可以目的地相同,也可以不同。 82 如下面,虽然decision分出了3条供选择的边,但是边的目的地都是end节点,只是边的名称不同 --> 83 <decision name="Decide Which Action" 84 handler="NetBpm.Example.LeaveOfAbsence.WhichWayDecision, NetBpm.Example.LeaveOfAbsence"> 85 <parameter name="attribute">RunTrace</parameter> 86 <transition name="approve" to="end"> 87 <action event="transition" handler="NetBpm.Example.LeaveOfAbsence.AutoSetAttributesAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 88 <parameter name="attribute">ToUserEmailSubject</parameter> 89 <parameter name="setValue">您的请假申请已经被批准 holiday from ${start date} to ${end date} with comment ${comment}</parameter> 90 </action> 91 </transition> 92 93 <transition name="disapprove" to="end" > 94 <action event="transition" handler="NetBpm.Example.LeaveOfAbsence.AutoSetAttributesAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 95 <parameter name="attribute">ToUserEmailSubject</parameter> 96 <parameter name="setValue">您的请假申请没有获得批准, holiday from ${start date} to ${end date} with comment ${comment}</parameter> 97 </action> 98 </transition> 99 100 <transition name="requestercancel" to="end"> 101 <action event="transition" handler="NetBpm.Example.LeaveOfAbsence.AutoSetAttributesAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 102 <parameter name="attribute">ToUserEmailSubject</parameter> 103 <parameter name="setValue">您取消了请假申请, holiday from ${start date} to ${end date} with comment ${comment}</parameter> 104 </action> 105 <!-- 请假人取消请假的时, 如果主管已经审批了, 则需要发邮件通知他 --> 106 <action event="transition" handler="NetBpm.Example.LeaveOfAbsence.EmailChiefAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 107 <!--- action的参数只能有3个, 切记切记, 调试的时候搞晕了--> 108 <parameter name="to">role(chief)</parameter> 109 <!--<parameter name="cancelMan">previousActor</parameter> --> 110 <parameter name="subject">请假申请被取消啦</parameter> 111 <parameter name="message"> requested a holiday from ${start date} to ${end date} with comment ${comment}</parameter> 112 </action> 113 </transition> 114 </decision> 115 116 117 <!-- ====================== --> 118 <!-- == CONCURRENT BLOCK == --> 119 <!-- ====================== --> 120 <!-- 解释:定义并发块,concurrent-block一定包括一个fork,一个join,且边不可越出其界。concurrent-block是可以嵌套的 --> 121 <concurrent-block> 122 <!-- 定义fork,若没有定义forkhandler,那么其在fork flow时将按照默认行为执行 --> 123 <fork name="Is Cancel Fork"> 124 <transition name="CancelLeaveRequest" to="Request Cancel" /> 125 <transition name="evaluation" to="IsChiefDecision" /> 126 </fork> 127 128 <!-- 定义join,此处定义了joinhandler,则当有forked flow到达join时,将根据该委托判断是否要激活父flow, 129 若没有定义joinhandler,那么将按照默认行为(AndJoin委托类,也就是所有forked flow都汇聚到达Join才激活父flow)执行 --> 130 <join name="join before decided" handler="NetBpm.Example.LeaveOfAbsence.AnyOneJoin, NetBpm.Example.LeaveOfAbsence"> 131 <transition to="Decide Which Action" /> 132 </join> 133 134 <activity-state name="Request Cancel"> 135 <description>在请假申请被最终审批前, 您可以在这里取消申请.</description> 136 <role>requester</role> 137 <!-- fields are optional. they limit the access to attributes in an activity --> 138 <field attribute="start date" access="read-only" /> 139 <field attribute="end date" access="read-only" /> 140 141 <!--eg。请假理由备注先不被看到 142 <field attribute="leave days" access="read-only" /> 143 <field attribute="comment" access="read-only" /> 144 --> 145 <action event="perform-of-activity" handler="NetBpm.Example.LeaveOfAbsence.AutoSetAttributesAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 146 <parameter name="attribute">RunTrace</parameter> 147 <parameter name="setValue">requestercancel</parameter> 148 </action> 149 <transition to="join before decided" /> 150 </activity-state> 151 152 <decision name="IsChiefDecision" handler="NetBpm.Example.LeaveOfAbsence.IsInRoleDecision, NetBpm.Example.LeaveOfAbsence"> 153 <parameter name="checkrole">chief</parameter> 154 <transition name="isChief" to="BossApprove" /> 155 <transition name="isNotChief" to="ChiefApprove" /> 156 </decision> 157 158 <activity-state name="ChiefApprove"> 159 <description>您需要在这里对该请假单进行审批</description> 160 <assignment handler="NetBpm.Example.LeaveOfAbsence.AssignmentExpressionResolver, NetBpm.Example.LeaveOfAbsence"> 161 <parameter name="expression" >role(requester)->group(hierarchy)->role(chief)</parameter> 162 </assignment> 163 <role>chief</role> 164 <field attribute="requester" access="read-only" /> 165 <field attribute="start date" access="read-only" /> 166 <field attribute="end date" access="read-only" /> 167 <field attribute="Chief evaluation result" access="write-only" /> 168 <action event="perform-of-activity" handler="NetBpm.Example.LeaveOfAbsence.EvluationResultAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 169 <parameter name="attribute">RunTrace</parameter> 170 <parameter name="setValueAttribute">Chief evaluation result</parameter> 171 </action> 172 <transition to="IsMoreTenDays" /> 173 </activity-state> 174 175 <activity-state name="BossApprove"> 176 <description>您需要在这里对该请假单进行审批</description> 177 <assignment handler="NetBpm.Example.LeaveOfAbsence.AssignmentExpressionResolver, NetBpm.Example.LeaveOfAbsence"> 178 <parameter name="expression" >role(requester)->group(hierarchy)->role(boss)</parameter> 179 </assignment> 180 <role>boss</role> 181 <field attribute="requester" access="read-only" /> 182 <field attribute="chief" access="read-only" /> 183 <field attribute="start date" access="read-only" /> 184 <field attribute="end date" access="read-only" /> 185 <!-- 理论上Boss不需要看到主管是否同意,因为不同意就不会到他这里来 186 <field attribute="leave days" access="read-only" /> 187 <field attribute="Chief evaluation result" access="read-only" /> 188 --> 189 <field attribute="Boss evaluation result" access="write-only" /> 190 <action event="perform-of-activity" handler="NetBpm.Example.LeaveOfAbsence.EvluationResultAction, NetBpm.Example.LeaveOfAbsence" on-exception="log"> 191 <parameter name="attribute">RunTrace</parameter> 192 <parameter name="setValueAttribute">Boss evaluation result</parameter> 193 </action> 194 <transition to="join before decided" /> 195 </activity-state> 196 197 <decision name="IsMoreTenDays" handler="NetBpm.Example.LeaveOfAbsence.IsMoreOrLessDecision, NetBpm.Example.LeaveOfAbsence"> 198 <parameter name="attribute">leave days</parameter> 199 <parameter name="dividingDays">10</parameter> 200 <!--考虑扩展,形成对数值比较类的通用 <parameter name="datatype">float</parameter> 201 <parameter name="compareType">More</parameter> --> 202 <transition name="IsMore" to="BossApprove" /> 203 <transition name="IsnotMore" to="join before decided" /> 204 </decision> 205 206 </concurrent-block> 207 208</process-definition> 209 流程定义之webinterface.xml 1<?xml version="1.0"?> 2 3<!-- 关于webinterface.xml如何定义,请严格按照nPdl规定 4 只有需要人操作的节点, 也就是activity-state(包括StartState), 在该文件中才在需要进行定义,指定如何显示web表单等 --> 5<web-interface> 6 7 <!-- ==================== --> 8 <!-- == PROCESS IMAGE == --> 9 <!-- ==================== --> 10 <!-- 定义该流程的流程图片 --> 11 <image name="web/leavedemo.gif" mime-type="image/gif" width="510" height="560" /> 12 13 <!-- ================ --> 14 <!-- == ACTIVITIES == --> 15 <!-- ================ --> 16 <activity-state name="start leave request"> 17 <!--定义该节点在流程图中的坐标--> 18 <image-coordinates> 19 <x1>285</x1> 20 <y1>54</y1> 21 <x2>307</x2> 22 <y2>76</y2> 23 </image-coordinates> 24 <!--逐个定义该节点fields的web显示方式,htmlformatter是委托类,可以充分利用其委托类的特性--> 25 <field attribute="start date"> 26 <name>开始时间</name> 27 <description>在此处填写您想要在何时开始请假</description> 28 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateInput, NetBpm" > 29 <parameter name="dateFormat">dd/MM/yyyy</parameter> 30 </htmlformatter> 31 </field> 32 <field attribute="end date"> 33 <name>结束时间</name> 34 <description>在此处填写您想要在何时结束请假</description> 35 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateInput, NetBpm" > 36 <parameter name="dateFormat">dd/MM/yyyy</parameter> 37 </htmlformatter> 38 </field> 39 <field attribute="leave days"> 40 <name>请假天数(单位:天)</name> 41 <description>在此处填写您请假的天数(以后改进为系统自动计算)</description> 42 <htmlformatter class="NetBpm.Example.LeaveOfAbsence.TextIntergerInput, NetBpm.Example.LeaveOfAbsence" > 43 </htmlformatter> 44 </field> 45 <field attribute="comment"> 46 <name>请假理由</name> 47 <description>在此处填写您请假的理由或者其他需要说明的信息</description> 48 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.TextAreaInput, NetBpm"> 49 <parameter name="rows">5</parameter> 50 <parameter name="cols">20</parameter> 51 </htmlformatter> 52 </field> 53 </activity-state> 54 55 <activity-state name="Request Cancel"> 56 <image-coordinates> 57 <x1>287</x1> 58 <y1>146</y1> 59 <x2>420</x2> 60 <y2>178</y2> 61 </image-coordinates> 62 <field attribute="start date"> 63 <name>开始时间</name> 64 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" > 65 <parameter name="dateFormat">dd/MM/yyyy</parameter> 66 </htmlformatter> 67 </field> 68 <field attribute="end date"> 69 <name>结束时间</name> 70 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" > 71 <parameter name="dateFormat">dd/MM/yyyy</parameter> 72 </htmlformatter> 73 </field> 74 75 </activity-state> 76 77 <activity-state name="ChiefApprove"> 78 <image-coordinates> 79 <x1>173</x1> 80 <y1>220</y1> 81 <x2>295</x2> 82 <y2>253</y2> 83 </image-coordinates> 84 <field attribute="requester"> 85 <name>申请人</name> 86 <description>提交请假申请的员工</description> 87 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.PersonLabel, NetBpm" /> 88 </field> 89 <field attribute="start date"> 90 <name>开始时间</name> 91 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" > 92 <parameter name="dateFormat">dd/MM/yyyy</parameter> 93 </htmlformatter> 94 </field> 95 <field attribute="end date"> 96 <name>结束时间</name> 97 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" > 98 <parameter name="dateFormat">dd/MM/yyyy</parameter> 99 </htmlformatter> 100 </field> 101 <field attribute="Chief evaluation result"> 102 <name>主管审批意见</name> 103 <description>请审批该员工的请假单</description> 104 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.EvaluationInput" /> 105 </field> 106 </activity-state> 107 108 <activity-state name="BossApprove"> 109 <image-coordinates> 110 <x1>101</x1> 111 <y1>356</y1> 112 <x2>218</x2> 113 <y2>390</y2> 114 </image-coordinates> 115 <field attribute="requester"> 116 <name>申请人</name> 117 <description>提交请假申请的员工</description> 118 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.PersonLabel, NetBpm" /> 119 </field> 120 <field attribute="chief"> 121 <name>主管审批</name> 122 <description>同意该员工请假的主管领导</description> 123 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.PersonLabel, NetBpm" /> 124 </field> 125 <field attribute="start date"> 126 <name>开始时间</name> 127 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" > 128 <parameter name="dateFormat">dd/MM/yyyy</parameter> 129 </htmlformatter> 130 </field> 131 <field attribute="end date"> 132 <name>结束时间</name> 133 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" > 134 <parameter name="dateFormat">dd/MM/yyyy</parameter> 135 </htmlformatter> 136 </field> 137 <field attribute="Boss evaluation result"> 138 <name>老板审批意见</name> 139 <description>该员工请假天数大于10天, 请您审批该员工的请假单</description> 140 <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.EvaluationInput" /> 141 </field> 142 </activity-state> 143</web-interface> 144 流程定义之动态委托类 委托类包含在lib文件夹下的程序集中。因为委托类数目众多,这里仅贴出几个典型的委托类, 其源码工程若需要请看这里: 1. NetBpm.Example.LeaveOfAbsence.AutoSetAttributionsAction:该委托类设计为一个通用委托类,这里用来设置表识属性,如流程经过用户取消请假路径,则把RunTrace属性设置为requestercancel,供WhichWayDicision作判断用。 1using System; 2using System.Collections; 3using log4net; 4using NetBpm.Workflow.Organisation; 5using NetBpm.Workflow.Delegation; 6using NetBpm.Workflow.Delegation.Impl; 7 8namespace NetBpm.Example.LeaveOfAbsence 9{ 10 /// <summary> 11 /// 通用Action类, 改类用来设置属性, 把值(action参数setValue)设置给属性(action参数attribute) 12 /// by Luben 13 /// </summary> 14 public class AutoSetAttributesAction : IActionHandler 15 { 16 private static readonly ILog log = LogManager.GetLogger(typeof(AutoSetAttributesAction)); 17 private static readonly AttributeExpressionResolver _attributeExpressionResolver; 18 19 static AutoSetAttributesAction() 20 { 21 _attributeExpressionResolver = AttributeExpressionResolver.Instance; 22 } 23 24 public void Run(IActionContext actionContext) 25 { 26 IDictionary configuration = actionContext.GetConfiguration(); 27 28 String setAttributeName = (String)configuration["attribute"]; 29 String setValue = (String)configuration["setValue"]; 30 setValue = _attributeExpressionResolver.ResolveAttributeExpression(setValue, actionContext); 31 32 actionContext.SetAttribute(setAttributeName, setValue); 33 log.Info("设置属性" + setAttributeName + "的值为:" + setValue); 34 } 35 } 36} 37 38 39 2. NetBpm.Example.LeaveOfAbsence.AnyOneJoin: 该委托主要用来设置激活父flow机制,这里是只要任何一条路径到达了join,则激活父flow,流程往下流。 1using log4net; 2using NetBpm.Workflow.Execution.Impl; 3using System.Collections; 4using NetBpm.Workflow.Delegation; 5using Nullables; 6 7namespace NetBpm.Example.LeaveOfAbsence 8{ 9 /// <summary> 10 /// 只要任何一个Subflow到达了该Join, 就激活Parent flow 11 /// by Luben 12 /// </summary> 13 public class AnyOneJoin : IJoinHandler 14 { 15 private static readonly ILog log = LogManager.GetLogger(typeof(AnyOneJoin)); 16 17 public bool Join(IJoinContext joinContext) 18 { 19 bool reactivateParent = true; 20 21 log.Debug("flow " + joinContext.GetFlow().Name + " is joining : " + reactivateParent); 22 23 // 取消其他并行的flow。这里存在一个同步问题,如果此时在flow的执行者正在performacitivity,那么要考虑flow的锁定 24 IEnumerator iter = joinContext.GetOtherActiveConcurrentFlows().GetEnumerator(); 25 while (iter.MoveNext()) 26 { 27 FlowImpl concurrentFlow = (FlowImpl)iter.Current; 28 concurrentFlow.ActorId = null; 29 concurrentFlow.EndNullable = System.DateTime.Now; 30 } 31 32 return reactivateParent; 33 } 34 } 35} 36 3. NetBpm.Example.LeaveOfAbsence.WhichWayDecision:该委托根据流程实际流过路径,根据标识属性RunTrace等进行走哪条边的抉择,如注释。 1using System; 2using NetBpm.Workflow.Delegation; 3 4 5namespace NetBpm.Example.LeaveOfAbsence 6{ 7 /// <summary> 8 /// 根据流程走的路径, 9 /// 1)“主管或者老板批准”-‘approve’:修改员工休假的总天数,设定发给用户E-Mail的信息。 10 /// 2)“主管或者老板否决”-“disapprove”:设定发给用户E-Mail的信息。 11 /// 3)“撤销”-"cancel"-设定发给用户E-Mail的信息。如果主管批准,要发给主管消息说明已经撤销。 12 /// 判断走哪一条路 13 /// by LuBen 14 /// </summary> 15 public class WhichWayDecision : IDecisionHandler 16 { 17 public String Decide(IDecisionContext decisionContext) 18 { 19 // 默认为apprvoe 20 String transitionName = "approve"; 21 22 // runtrace是表示属性,在前面的流过的路径action中被设置 23 String runtrace = (String)decisionContext.GetAttribute("RunTrace"); 24 25 if (runtrace.IndexOf("disapprove") != -1) 26 { 27 transitionName = "disapprove"; 28 } 29 else if (runtrace.Equals("requestercancel")) 30 { 31 transitionName = "requestercancel"; 32 } 33 return transitionName; 34 } 35 } 36} 37 38 后记 本文仅仅是一个示例,给大家提供一个运用nPdl定义NetBPM流程的参考,如果要把该流程投入现实中使用显然还需要做很多优化。该示例更多的是给大家展示流程定义中action可以定义多个, decision出来的transition可以到达同一条目的节点但名字却不一样等等. 示例中委托类的耦合性太高, 很多地方并不需要那样做, 如一个decision里面进行了2个判断: 判断是否大于10天, 判断是否审批同意, 这个完全可以拆分为两个独立的decision来做. 委托类设计成为高度可重用的, 耦合性低的通用类, 才是我们的目标. 待写:NetBPM实现会签;NetBPM Q&A(不断更新)
  • 相关阅读:
    Maven核心简析
    块/文件/对象存储对比性概述
    Java SE-基本数据类型对应包装类
    Maven+eclipse快速入门
    IaaS、PaaS、SaaS、CaaS、MaaS五者的区别
    Collections.shuffle()源码分析
    java集合继承关系图
    ArrayList和LinkedList的区别
    ArrayList的实现原理
    session以及分布式服务器session共享
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/3877983.html
Copyright © 2011-2022 走看看