项目中的流程及类似业务的设计模式总结(转)

说到业务流程,可能是我做过的项目中涉及业务最多的一个方面了。除了在流程设计之外,在一些考核系统、产业审批、还有很多地方,都用到相似的设计思路,在此一并总结一下。再说到模式,并不是因为流行才用这个词,而是因为这里总结的东西确实只能是个参考,是我解决问题的处理方式与思路,当然几乎相同的项目中,有时我用到很多相同的代码,所以又可以看到是一个原型系统。


什么什么?不是已经有那么多BPMS系统了吗?比如JBPM啊,为啥还要搞一个流程设计模式?怎么说呢,用着不舒服呗,如果项目的流程很规范,那是不错,如果是定制的系统,有很多特殊或者非正常的需求,那还是自己搞比较好。其实这些工作流产品,你不觉得它们的核心都差不多吗(其实笔者也没多过的好好研究过,汗~)?其实它们也是符合我总结的这个流程模式的,当然我会去掉一些繁琐的东西,也会加上些个性化的东西。如果你将会的是产品,可能流程需求自己定,用BPMS,如果你将会的是项目,流程等很多方面由不得你。做产品与做项目差别还是很大的,全面了解这个模式,做需求时就能比用户考虑的更全面,知道什么样的需求就到位了,也就能选择怎么做,设计的更灵活,更可靠,还更简洁的系统。比如用户讲退回操作,就要问清楚退回的意思,是完全抹去后面的任务,还是就当成普通的任务提交,只不过提交给自己。

插一句:有时候流程会配合表单系统,设计非常多的表,后面会提到方法。


一、开门见山的讲:流程模式中的核心有几个重点。

1、是岗位定义。包括流程的岗位,岗位的角色,前后岗位的操作,一些分支条件等主要内容。那么我曾经还定义过什么呢?包括岗位对应的表单名称,岗位除了配置角色,还要配置是到角色中的一个人,还是到角色?岗位对应的菜单名称叫什么。另外还有岗位是主流程岗位还是附属岗位。还要定义本岗位操作的期限是多少,提醒提前多久,超时要不要报警。岗位还要定义其它一切可能与岗位有关的东东。怎么样,自己定义的话,内容非常丰富吧!更长远一点,你可以定义一个岗位是一个webservice,定义好地址信息,甚至参数都定义进来。对了,还可以岗位启动数据交换任务,反正想配置的东西都记录在一起,反正自己用嘛。

2、岗位操作。对于操作,还要定义操作的角色,通常岗位与本岗位的操作角色是一样的,也有不一样的。些操作提交的下一岗位的角色的人员要不要设定过滤条件?有过某岗位有高级办理与普通办理之分。为啥不设计成两个角色呢?后来客户新领导要求呗。

这里,遇到过的常见问题:对于项目中只有简单的小流程,有些人会想不引入工作流吧,那样搞大了。要不用状态机?可是状态机从名字说就是状态与状态的变化条件,并不包括最重要的任务调度,少了这个灵活性欠缺。有的人用工作流产品,只定义了一些与岗位有关的东西,包括分支条件啊,但其它很多与岗位相关的东西就不知道往那里定义了,往往是配置项中写一点,或者字典项中写一点,或者常量中写一点,或者根本就写在程序中。所以了解模式后,从整体上把握各东西的摆放与命名,而且更合理。


3、任务调度定义。任务调度也应该算定义中的一部分,它是与岗位定义的操作密切相关的,可以看成是操作的结果,这里因为重要性以及非常的内涵而分开。简单的有串行任务A-->B,就是一个岗位产生下一个岗位的任务。还有并行,一个岗位产生后面很多并行的任务,就是:A-->BBBBB-->A(C)。这些是最基本的了,还有子流程,就是主岗位任务挂起。

那我这里还做过很多更复杂的调度。比如A-->B--B--B-->A(C),与前者不同是B一个接一个来做的,还有的就语言描述吧。比如并行的任务突然撤销一个,或者增加一个,或者换当前任务人,而用户不愿意撤回再分配。比如任务A可以产生流程中定义过,但不是状态的任务,最常用的情况是我设计过一些【阅读】岗位,很多岗位都可以产生这个岗位的任务,甚至要求回执,但绝对不会影响流程的当前状态。反正是真正的随心所欲,只要用户有想法,临时增加,销毁,条件挂起,变更人员,人工后台强制结束别人任务等等,只要用户想的到,就能办的到。当然非正常操作都要做好记录,变更人时间原因什么的。更长远一点,前面提到的webservice可以是多个其它应用的任务,可以提交到多个并行的ws应用,同时在自己系统中产生几个外部应用要完成的任务供回调。回调时判断其它任务是不是都完成了,完成了就推动工作流前进。

任务调度多数情况下,可以看成是一种操作规则,那其实只要实现了规则调度关系,其实的相关部分可以用接口或者抽象类来做。一般工作流产品中的所有业务的任务表都在一起,所以调度具体的任务。但自己设计的时候,可以请假是这几个表,报销是那几个表,但操作关系是通用的,都有串行调度,那请假主表与报销主表可以抽象中业务对象,必须包含ID,状态等字段。请假任务表与报销任务表也可能是不一样的,那可以抽象成任务对象,至少包含业务对象ID,任务开始时间,任务角色,任务完成人待内容。


4、任务操作实现。任务操作就是任务调度后,由具体业务中的具体人完成任务。前面在调度过程中已经按定义的调度方式,由前一步操作产生了新的任务。新的任务可能只是init状态,当前人点开过任务就是todo状态,当前人完成任务就是done状态。通常一个人完成的任务含有两方面的内容,一方面是对表单进行处理,填写意见啥的,也有可能做什么设置,比如选择下一步操作及涉及的人员。另一方面就是推动工作流。一般来说用产品的话,推动工作流程是封装好的过程,而保存本岗位的信息是由用户处理的时候,当然存在用户设计的地方。这两部分操作是可以包装成一个服务的,而且是一个事务的。实现的方式可以是AOP引入,保存自己信息的方法外做流程的处理,也可以自己的service中引入工作流产品的服务。

而不用工作流产品时,一个岗位就一个任务,一部分字段是属于流程推动来管理的,一部分字段是本岗位填写的内容。算是合二为一了,当然可能岗位填写的内容是主记录信息,还要同步写主表中。因为工作流产品只专注于任务调度,而其它填写内容它无法管也管不了,它的任务也不让你碰,你只能用提供的接口访问得到任务。自己合二为一的好处就是任务内容整合在一条记录中了,而且才有可能动手处理各种情况,比如突然增加个任务,突然修改任务,突然枪毙一个任务,而且方便普通开发人员理解并处理这些情况。


二、与之相关的数据库设计与页面、类


1.与流程定义相关表:首先要说明的一点,从概念上来说,这些算是系统的配置信息一样,存在读多写少的情况,而且很少改变,可以放在内存中。另外,流程不一定要记录在数据库中,可以是XML,可以是配置文件,可以是其它任何可以表述的方式。

岗位信息表、操作信息表,这两张表就差不多够用了。根据实际情况也简化过一张表,不过表的记录当时非常的多。也可以弄一个流程信息表出来,定义版本,启动之类的,工作流中一般都有,有时候可以简化不要。

岗位信息表:基本的如岗位名称,ID,流程名称。自己可以再定义什么菜单名称,角色名称,具体人还是角色,表单地址,外部WS地址等任何与岗位关联的信息。

操作信息表:操作名称,ID,前一岗位、后一岗位,角色,按钮名称或者选择名称之类的。

2.与流程运行相关表:当然有一个主表,比如是请假信息主记录,另外有一个任务表,我一般是一个业务一个表,并不是都放在一起。工作流是做了抽象整合,而我是分散治之。任务表主要包括:任务ID,主记录ID,任务角色,任务人,任务状态,任务开始时间,任务结束时间,还可能包括任务填写内容。还有可能是做了什么选择。既然我把一个系统中的不同任务分开了,但基本任务要素设计成是一样的。这样我在任务调度中可以对抽象任务进行编程处理。可以认为工作流产品是把任务的公共字段放一个内部管理的表了,其它任务的内容用户来管理,而我是放在一起,只是调度抽象类管理公共部分,具体实现类记录各自不同的内容。

3.定义时的设计页面。这点是与工作流产品无法比的地方,产品都是可视化绘制流程图,但我一直用简单的列表页面来处理流程定义。显示流程时可以出简单的图。为什么呢?因为我定义的内容非常之多,调度随意设计,没有一个公共的方式绘图,而且不能可视化也问题不大,流程是我们来处理,或者用户的管理人员,以后只读基本不改,因为项目中满足用户多样的需求,所以没有精力时间弄这个,而且成本会高上去不值得。

4.最重要的类就是调度类,调度类只操作前面的流程运行相关的任务表。前面说过是要对抽象类编程的,因为调度是一种规则。调度类实现了任务的完成与新任务的产生的规则。比如提交了一个并行处理任务,就挂起当前人的任务,产生一批并行人员的任务。而并行人员的其中一人完成了自己的任务,就要校验其它人是不是都完成了,没完成就只完成自己的。其它人都完成了就把挂起的任务再启动起来。


三、与之相关的常用页面的设计与常用的方法

1.菜单设计:很多时候,用户要求菜单按岗位分出来,比如任务分成收件、审核、处理、答复等。正好这些菜单与岗位密切相关嘛,所以菜单配置的内容都可以整合到岗位中去,菜单名称,链接什么的,如果开始设计时岗位属性没想到,可以方便的加属性来用。

2.任务列表:任务表与主表JOIN一下就出来了,而且可以显示出各有特色的任务字段。

3.具体业务页面:通常要把一个业务的相关任务都取出来,分类组合以后显示在表单的不同位置,比如几个审核任务显示在审核处,当前任务人点开的具体业务页面,比如也是审核,那审核的地方颜色特殊,并可以点开一个录入信息页,而不要在主页面中填写,主页面是汇总一批同岗位任务后显示用的。比如多人审核时,审核处显示了张三7.1日:同意。李四7.2日:同意。新的审核人员有此处任务,就点开此处录入,录入好刷新内容,又增加了王五7.3:同意。

主页面中主要做查看,有任务的人在点开页面中填写后,回到主页面选择下一步操作是什么,如果配置了任务到人,还要进一步选择下一步的人员。之后就可以提交了。有些人设计中把东西混乱在一起,没有层次感,维护的人要吃药了。


四、举例与总结:

比如一下系统中有报销业务,有请假业务。主要的表有以下一些:

流程信息表(有时候省了,不会有新流程时),岗位信息表,操作信息表(有时候简单的也省了),报销主表,报销任务表,报销日志表(有时候也省了,任务本身也表示了日志),请假主表,请假任务表,请假日志表(同上也会省了),主要的就这些了。

其它一些附件表什么的就不提了,专门提一下有时候会用到的表单系统。这样表单与报销表单不一样,由于是非常多的,一般用XSTL配合XML来做,表单的定义在定义表单的一个字段中,实际业务中填写的表单也在业务表单一个字段中。表单通常只是在一个特定的岗位中填写,抽象的来说与附件相似,并不参与到流程管理,调度中来。这时只需要处理到岗位中可以配置本岗位填写哪些表单而已。

类呢?主要有岗位信息类,操作信息类,报销主表类并实现流程主表接口,比如流程会置其状态的。报销任务类并实现流程任务接口,比如流程会根据用户操作选择一个调度方式处理任务,完成一些任务,产生一些任务。请假主表类并实现流程主表接口,请假任务类并实现流程任务接口。也可以继承抽象类。

而任务调度就是对流程主表接口、任务接口进行编程。真正操作那个业务就传哪个业务的实现类进来。以后做其它项目,那部分复用。


总的来说,就是定一个模型,真实的业务就是按模型走。抽象的说模型是类,业务是对象。生活中的规章是模型,你按规章办事就是业务。模型的东西放一起,业务的东西放一起,把里面的东西组织好,不能把应该定义的东西到处乱放或者写死在代码里,也不应该把与一个任务相关的填写内容乱放,再简单的流程,最好也单独写一个任务调度类。为什么我一般不用工作流产品?因为它包括一部分定义的东西还不全,又包含了一部分业务的东西,也不全,调度算法也不全,一些特殊的统计要求也不好弄,相反一些画图,启动啊,流程版本啊,在我看来又不是特别重要的,无所谓的,那不如按此思路自己弄的好,而且也不是每次项目都是重新弄,可以说是做多了就有原型系统了,改改也快。

如果都是规范的业务,那工作流肯定方便了。否则又要全面把握复杂的业务,又要用好工作流,很多时候项目都比较乱!

五,其它类似系统的设计思路

当把握好工作流的整体设计思路后,再设计其它类似的都很简单并且规范。比如任务都要有状态,产生时间、开始时间结束时间,用户不提也要都设计上,可能有规则适用在其上。有的设计时间只有一个时间,那么后面的一些功能就不好弄了,比如产生时间与开始时间就知道这个人是不是及时查自己的任务。开始时间与结束时间就知道办理时效,而有的结束时间很重要,要记录在主表中,比如办结时间。但任务表中也不能省略,而且任务表是这个办结的源头。任务是到人还是到角色也很重要,有的系统一会到角色,一会到人。那设计中都要有字段,有的人只设计了人,提交给角色时,找出角色中所有人的,一人一份任务,冗余数据很多,而且新配置的角色看不到此任务。离开此角色的人,还记录着他有条待办任务。

体会到配置、调度与业务之间的关系很重要。。。

比如做考核时,考核的规则就是定义部分,每一个考核人都是一个业务。下发考核表等于给考核人员产生一条条任务,任务里有考核项。即方便考核人查找自己的任务,又可以填写提交。提交时,单位的组织结构可以当成提交规则的一部分,比如下级提交给哪个上级。当任务成份比较大时,又可以把任务部分与考核分分开。有此任务是关联考核分的,有些任务是写意见的。有一个大的思路控制,系统都会很整洁。

比如做一些建设工程审批监控,可以定义一类项目的审批,并配置部分的前置要求。当一个具体的项目进行时,预先产生所有的审批任务,都是init状态。通过人工或者是对接方式,可以获取实际的进展,更新任务时可以状态同步,并校验前置关系。实际中审批还分阶段,阶段也设计成阶段任务,由其中的审批任务构成,自动按规则更新状态。

即使是一个小的通知与反馈,那么也可以配置什么类型的通知要反馈,通知后就可以预先产生反馈的任务提醒当事人。而这个规则就可以在流程规则中放一起统一管理。实际中有的设计是完成当前任务,不去预先产生新任务,而又要繁琐的根据完成的任务与规则产生待办任务。


有了模式与思路,可以预先完善你的需求分析,可以选择用产品还是自己弄,可以规范库,表,类的设计与开发,相似情况可以尽量套用,结果发现用户后来提出的其它要求都能满足。



---------------------
作者:herriman
来源:CSDN
原文:https://blog.csdn.net/herriman/article/details/51815925
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/hao987/p/9958989.html