??xml version="1.0" encoding="utf-8" standalone="yes"?>
05q的时候忙着和现在的老婆谈那从来没谈q而导致过分饥渴的恋爱Q?6q的时候新配置了机器,忙着通关使命召唤和生化危机;07q的时候和张祖良一L?a >AJAX企业U开?/a>Q第一ơ翻译,忙得像黄牛,慢得像蜗牛,在心里祈P译出来的东西不被骂好Q?8q的时候和丁雪峰、d令又一L?a >SpringȝQ第二次译Q熟l了一些,但是每一个句子还是要׃很多旉Q很多时候还得一个词一个词的确认,译Ҏ(gu)来说是个苦力z,W一ơ翻译完我就告诉自己不要再翻译了Q但是Springȝ实是一本好书,完全是书本n吸引了我Q同样在心里祷Q不要糟y了q本书?9q了Q和辛鹏一起完成这本《Head First Process-深入出程》,q是祷Q千万不要写出垃圾,有时候,我常惻I有必要这么辛苦吗Q我是一个喜Ƣ意淫的人,l常把思A抛到了多q之后,在未来里z洋自得Q于是回来时有了动力?br />
我负责该书的W一部分Q包括了工作的控制模式、资源模式、数据控制模式与异常处理模式Q包括了对三U流E规范的介绍、对开源工作流的介l、对jBPM4的分析。辛鹏负责该书的后半部分Q他Ҏ(gu)E应用有着非常丰富的经验,目前他正在杭州实施一个BPM的大目Q其中包括了完整的IBM产品套gQ包括了企业集成和ESB。很多h认ؓ工作只是OAQ这其实是一个误区,工作确实在OA里应用的非常多,但这仅仅只是一个方面。说实话Q我Ҏ(gu)书也非常的期待,非常期待辛鹏在书中分享他众多的实施经验,他是一个非常勤奋的人,q点让我钦佩不止Q常常想Q等我到?0多岁Q还会不会有一颗勤奋的心?br />
家住燕郊Q上班在东直门,每天在\上四个小Ӟ挤那传说中的930Q时常安慰自己:哥挤的不?30Q哥挤的是寂寞。谢谢老婆Q尽还q着房贷存在着心理障碍Q但是还是ؓ我在东直门租了个房子Q下周v可以走路上班了Q这样也会有了更多的旉来完成这本书?br />
q是那句话:战战兢兢?br />
十一q完Q公司的新项目也开始了Q时网站。技术栈包括了:OSGI、JCR、REST、渐q式增强。该目有个巨大的亮点,不是徐昊是我们的技术leaderQ而是开发h员中一半是女生Q这h天pair的时候就生活在祖国的花园中了?br />
希望能写些有价值的东西Q征得刘江的同意Q将会在博客q蝲部分章节。第一部分q蝲的将是工作流的资源模式,内容包括前言、基本概c创建模式、推模式、拉模式、迂回模式、自动开始模式、可见性模式、多资源模式以及最后的结。限于篇q,会分节q行q蝲。考虑到复刉烦,会?a >开放流E社?/a>q蝲所有内容,博客会连载概要ƈ提供链接?br />
]]>
目标Q?/font> jBPM-side ProcessDesigner是一个独立的设计器,Z Flex技术。其目的在于既得程序开发h员能够基于其q行业务程的徏模,同时业务人员也能够基于其q行单的建模和修改,例如修改节点的顺序、参与者等操作。此外, jBPM-side ProcessDesignerh很高的可配置性,在流E定?/font> scheme变化的情况下Q能够很快的做出适配。即其与具体的流E定义语a无关Q可以对 jPDL?/font> XPDL?/font> BPEL都进行徏模?/font> jBPM-side ProcessDesigner的数据核心是 xml?/font>
功能规划Q?/font>
一?/span> 囑Ş建模
支持程模型与图形元素的一一对应Q支持通过囑Ş元素来进行流E的建模。流E模型与囑Ş元素之间通过 xmlq行互相转换。图形徏模方面,支持囑Ş元素的拖拽、定位、复制、粘_支持快捷键操作,例如 do/undo?/font> delete?/font>
二?/span> 程参与者的适配导入
支持在进行流E徏模时Q适配导入程参与者。在q行人工参与节点定义Ӟ选择参与者。进行h?/font> /部门 /角色的本地徏模,提供最单的必需属性?/font>
三?/span> 囑Ş展现?/font> xml~辑的互相切?/font>
支持程囑Ş?/font> xml~辑的切换,支持 xml定义的本地导入和导出?/font>
四?/span> 程的分包与版本理
支持程定义的分包和版本理Q需要服务器端的支持?/font>
五?/span> 与服务器端的q程调用
在支持服务器端的q程调用之前Q?/font> jBPM-side ProcessDesigner仅仅是本?/font> xml的导入导出徏模。采?/font> restful-wsQ基?/font> xml在服务器与设计器之间传递数据?/font>
六?/span> 与业务适配?/font> DSL
七?/span> 程的权限管?/font>
支持Ҏ(gu)E定义的分类权限理Q不同业务部门对属于自己的流E定义有各自的管理权限。此功能独立?/font> jBPM-side ProcessDesignerQ但是需要通过契约使得 jBPM-side ProcessDesignerҎ(gu)E定义的展现q行qo?/font>
在拥挤的公交车上d《工作流理(模型、方法和pȝ)》,自从搬完Ӟ上班的\途突然变得遥q?/p>
q本书确实是按照它的副标题组l的Q分别介l工作流的徏模模型、应用工作流开发的Ҏ(gu)以及部分商业的工作流产品?br />
对petri|的介绍是这本书的重点,如果惛_petri|有个大概的了解而又不愿意接触深奥的数学Q那么可以一诅R本书随后分析了如何Ҏ(gu)E模型进行分
析,包括对徏模正性与否的定量分析以及对资源运行效率的定性分析。至于介l的工作品,因ؓq代久远Q可L不高。应用工作流开发的Ҏ(gu)更是理?
了,不过作ؓ一?000q的书,里面提到的一些原则还是很有敏L意思,例如和客户在一赗P代开发、交的重要性等{?/p>
dq本书,加上先前的范玉顺的书Q突然就明白Z么BPEL会如此之行Q原因在于它们都非常BPR的概念,即业务流E重l。也是从一开始,工作
系l就是瞄准BPRq个目标来的Q想利用工作系l将整个企业的业务流E都理h。目标如此远大,整合自然是不能避免,整合包括了对人员的整合,也包
括了对ITpȝ的集成。如此以来,恍然大?zhn)QBPELq种服务集成的执行语a无怪乎会大U大紫了。至于说国内最普遍的工作流应用Q将工作引擎嵌入应
用系l中Q分LE逻辑与业务逻辑Q则自然M了大雅之堂了。一句话_是国内应用工作的层次太低。或者反q来也可以理解:现在的所谓BPM软g都眼
高手低,不太适合国内的应用?/p>
可是问题依旧存在Q即BPELҎ(gu)上说是一U执行语aQ要业务人员理解直是Zh所难,所以BPMN应运而生。好吧,BPMN有了Q自然BPMN?
BPEL的映就出现了,可惜q终I是一厢情愿,一U是业务建模语言Q一U是计算机执行语aQ中间的代沟?0?0q宽。就像科比,筐在他眼里比大?
q广阔?/p>
此外QBPEL的应用还存在一个天然的障碍Q即应用集成从来都不是一件轻杄事情。将接口用web
service包装一下就SOA了?面向服务了Q这D你也信,那可真是你服务,你全家才服务呢。应用集成不LQ所谓的企业敏捷性:能够Ҏ(gu)外部环境
的变化迅速调整服务编排流E那自然是镜中月Q水中花了。君不见Q无数程序员们在开口大骂:靠,程又要调整Q早吃屎了?Q?/p>
所以结论有?
1、国内的嵌入式工作流应用q是什么适用q什么吧Q和XPDL\BPEL都无养I
2、一心要SOA、要BPEL。那别指望它能减工作量Q也别指望流E能够迅速修改;
3、要对企业流E进行敏L理,那就考虑文档化,别考虑执行?/p>
大概׃三天的时间读完这本书Q书本n也不厚,读v来很快。这本书出版?/span>2001q_所以对它也没有抱有很大的期望,但是q不错,特别是前三章Q很有些惊喜。后面关于工作流仿真的描qC很到位。但是关于技术实玎ͼ则大都略q了?/span>
ȝ一下里面个得不错的部分?/span>
W一章很不错Q强调ؓ什么需要工作流理pȝ?/span>
企业l营环境的变化:q去企业市场竞争主要围绕着如何提高生率进行,现在则是围绕C品的竞争而展开。新产品的h(hun)格L高于其h(hun)|通过竞争Qh(hun)格才逐渐接近价|产品失去独占期,同时也意味着产品生命周期的结束。与产品生命周期~短所对应的,是客户定制品数量的增加?/span>
在这U情况下Q传l串行的产品研制会g长品的上市旉Q同时串行过E也是在企业以功能ؓ核心划分l织机构下的必然产物?/span>
敏捷刉提出的背景Q用户需求多样化、个性化Q所有企业都处于一U连l改变、不可预见的市场环境中,此时问题的核心在于是否抓住机遇、快速响应市场、开发新产品。敏捷制造的基本思想是,企业能够Ҏ(gu)l变化、不可预的市场需求做出快速反应,面向市场的敏h。实现敏捷制造的关键是对企业q行敏捷化改造和重组。其中企业组l结构发生重大的变化Q传l的企业l织l构是功能部门制Q即按照不同的功能和职能讄不同的部门,上下U之间Ş成一个树型的l构。这U结构的~点在于Q每个单元都׃一U的功能单元q行理Q出现问题时Q每一U都会把责Q推到上一U,q样会造成部门职责不清。柔性底Q一个生产流E往往跨越多个部门Q部门之间的协调成本很高Q扯皮。需要徏立v面向程的组l机构,按照企业要实现的主要业务程来配|组l机构,以项目来l织人员Q减内部不必要的沟通协调成本,提高对市场的响应速度?/span>
由此Q需要工作流pȝ来对企业的流E进行分析和梳理。然后围l这些流E来q行企业的业务重l和攚w?/span>
W二章的亮点在于如何实施工作系l?/span>
工作的实施不同于普通的业务处理pȝQ它首先需要在战略层次上对企业的业务目标进行分析,定企业的战略目标和l织要求Q然后再q入到具体的实施阶段Q分Z个阶D:模型建立阶段、模型实例化阶段和模型执行阶Dc实施工作流的目的在于提高企业的柔性,能够Ҏ(gu)市场的变化不断改q其业务程。其中作者强调了工作的两个重要职责Q集成和仿真。工作流pȝ本n是一个完成流E徏模和程理的Y件系l,但是Z在企业的实际业务中得到有效的应用Q它必须和企业已有的或购买的其他业务pȝ实现集成Q通过集成来提高整个企?/span> 的应用水q_应用效率?/span>
W三章分析工作流pȝ的组成以?/span>WFMC定义的五个接口。很清晰?/span>
W四章到W八章描q具体商业品的大概技术实现?/span>XPDL规范和分布式的工作流Q由于现在已l是B/S软g的天下,所以里面的分布式在q里昑־理所当然。这部分可以跌?/span>
W九(ji)章讲qC者实现的一个工作流pȝCIMFlow。亮点在于分布式工作机的设计方案?/span>
核心思想是:多个工作机分配l多个部门,与这个部门相关的程或流E节点就p个部门专属的工作机执行Q部门可以各自独立修改这些流E或程节点。另外ؓ了集中管理,再设|一个主控工作流机,集中理q些部门工作机。这样可以提高流E的柔性。很赞的思想Q但是实现无疑复杂了?/span>
W十章讲如何在企业流E重l中应用工作。偶觉得Q这本书一旦上升到企业q营的层ơ讲解工作流Q马上就很赞了,O(∩_∩)O~。其中关于流E仿真部分很是好看,颠覆了自己对程仿真的观炏V以前认为是程仿真是确保流E徏模的逻辑正确Q属于Y件测试的范畴。这里的仿真却是Z业决{提供数据。需要注意的是对资源的定义。资源包括了人、业务系l、运营成本等{,很广义的概念?/span>
最后一章再ơ强调工作流集成能力的重要意义。不让我想起了BPEL?/span>
合上书,我想Q这是在讲工作流吗,( ?/span>o?/span> )?Q咋和我印象中的工作不一样哩。我惻I作者更的应该是一U高端的业务程理Q它既不是现有的工作、也不是BPM软gQ然而又不是BPGQ因为它理的流E是可以马上执行的。只能这么想Q作?/span>7q前作者对工作的理解Q期望太多?/span>
如果有电(sh)子版Q值得一读,如果买纸版,没有必要了?/span>
一?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
从用L角度分析工作系l的l成q里的用户分Zc:一cL应用pȝ开发h员(以后U开发h员)Q一cL应用pȝ的最l用P以后U最l用P。对于最l用戯言Q工作流pȝ往往是不能直接用的Q它需要由IT部门的开发h员嵌入到应用pȝ中。开发h员才是工作流pȝ的直接用者,q造成了问题:工作系l更多关注于开发h员的需求,例如如何快速开发、如何更好的嵌入业务逻辑{等Q而最l用L需求被或多或少的忽略了?/span>
q里从最l用L角度q行分析?/span>
1?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
面向开发h员的程设计?/span>
最l用户通过程设计器对业务程q行描述Q实际是一个流E徏模的q程。理ZQ业务分析师完成q个业务程建模的过E,q且业务分析师往往被假定ؓ非技术h员。对于业务分析而言Q流E徏模通常是抽象的Q一定程度上是模p的Q徏模的目的在于通过囑Ş的Ş式向其他释一个业务的q程Q图形只是一U方式,采用它只是它更易于理解和易于沟通,实际cM?/span>DSL。实际上企业的规章制度、文字描q的执行程都是对业务流E具体的描述方式?/span>
对于工作而言Q这个徏模所产生的流E是需要被引擎执行的。这p求流E中每一个节点的定义都是要有明确含义的,它需要被计算机明而准的解释。同ӞZ集成业务pȝ的需要,程模型定义往往带有很多额外的属性?/span>
所以现实中的流E设计器往往属性配|繁多。导致最l用户在打开设计器后Ҏ(gu)无从修改和徏模,他需要关注很多与业务无关的配|,无意中的修改往往产生程无法q行的后果?/span>
2?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
工作列?/span>
即Q务列表。工作流pȝ通过工作列表进行h工Q务的分配。最l用户通过该列表签收、处理每天的工作Q工作以工作的形式展现。对于工作项Q用h着多种业务操作Q签收、完成提交、收回、回退{等。对于分配给他h的工作项Q也存在着多种业务操作Q催办、提醒、时间限定等{?/span>
3?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
程q踪
用户在处理工作项Ӟ对该工作在流E中所处的位置q行查看Q了解当前流E的状态和执行情况。一般情况下Q流E追t以囑Ş化的方式展现。用户通过不同的图标和标示来区分流E中各个节点的状态和参与者信息?/span>
4?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
程实例理
包括程实例、节点实例、工作项实例的管理。改变状态,包括了挂赗重新启动、终止、蟩转等{。主要目的在于对程Zؓ执行错误q行人工q预以及Ҏ(gu)E信息的监控?/span>
二?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
pȝ架构
从用L角度分析完工作流pȝ的组成,q里从开发h员的角度分析工作系l的架构。系l架构里的每一部分是如何与用户使用的部分进行对应,以及每一部分在实现时需要注意的事项?/span>
1?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
整体构成
如图Q各模块分层l织Q位于上层的模块依赖于底层的模块。正如你所看到的,程定义模型位于整个工作系l的最低层Q因为它是整个工作流pȝ的基?/span>
程定义模型Q定义对程q行描述的所有对象。因为对程q行描述的本质就是利用这些模型进行徏模,所以这些模型对象的实现直接军_着工作系l对程的描q能力?/span>
l织l构适配器:工作系l在与业务系l进行集成时Q需要进行组l适配Q通过q一q程业务系l里的组l机构导入到工作系l里。具体实现时Q工作流pȝ需要徏立v自己的组l机构模型(包含在流E定义模型里Q,要适应多种业务pȝQ往往需要徏立多套模型,Ҏ(gu)具体情况q行切换。有多种方式完成q个适配Q最单的方式是利?/span>SQL配置d数据q行语义转换?/span>
程设计器:供用户用的可视化图形工兗每U图形都对应着一U流E定义模型。具体的实现?/span>Swing?/span>SWTQ但是基?/span>AJAX?/span>WEB设计器无疑会提供更好的可用性?/span>
程执行引擎Q将程定义模型解释为流E实例模型。利用这些流E实例模型完成流E的调度和执行。在工作系l里Q执行引擎是整个pȝ的核心。实现时不仅需要考虑各种程调度的实玎ͼq要考虑执行的效率、缓存、日志等{?/span>
工作引擎:解析参与者定义模型和工作定义模型,生成相应的工作项。对用户对工作项的操作作出响应?/span>
WEB应用Q工作流pȝ?/span>WEB展现。包括了工作列表、流E追t以及流E实例管理的操作和显C?/span>
程仿真Q对建立好的程模型q行q行仿真Q模拟流E模型的执行q程。目的在于发现流E徏模过E中的疏漏,发现由此D的流E不能运行?/span>
旉服务Q提供对整个程实例执行旉和Q务执行时间的控制Q根据规则触发相应的旉事gQ例如Q务超时、Q务预警等{。根据规则自动触发启动新的流E实例?/span>
业务集成Q提供工作流pȝ与业务系l的契合方式。典型的实现包括通过注册事g监听器和提供接口抽象c调用业务系l代码、提?/span>APIl业务系l调用、工作项驱动业务表单和脚本引擎执行业务逻辑脚本{等。特定于工作w动业务表单,为方便开发,l大多数的工作流厂商都提供了?sh)子表单的实现?/span>
2?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
Z事g的流E执行引?/span>
程执行引擎的主要职责就是负责流E的调度和执行?/span>
首先需要将程定义模型解释为流E实例模型,在定义模型和实例模型之间建立起对应关pR一个简单的对应关系如下图所C:
执行引擎流E定义模型的属性读取到相应的实例模型里Q由实例模型完成程的调度和执行。当Ӟ上图只是一个简单的描述Q实际情况要复杂的多Q特别是节点定义Q?/span>ActivityDefinitionQ,Ҏ(gu)实际应用Q往往存在着多种cdQ典型的有开始节点(StartDefinitionQ、Q务节点(TaskDefinitionQ、自动节点(AutoDefinitionQ、分裂节点(SplitDefinitionQ、汇聚节点(JoinDefinitionQ、结束节点(EndDefinitionQ等{。这些节点的实例Ҏ(gu)cd的不同执行不同的逻辑。其中,分裂节点实例和汇聚节点实例负责流E的调度Q它们决定流E的向Q通常情况下,它们会调用一个脚本引擎执行一D脚本来军_程的流向,同时Q也会提供对外暴露的接口Q由业务pȝ实现Q接口返回的l果军_程的流向。Q务节点实例和自动节点实例则负责流E的执行Qؓ保证程执行引擎职责的清C及对外围设施的松耦合Q它们只是发布相关的事gQ通过事g发布/订阅机制来触发具体的逻辑执行?/span>
典型的事件有程启动事g、流E结束事件、进入节点事件、离开节点事g、时间事件等。例如,d节点实例的进入节点事件将会触发工作项引擎生成工作(WorkitemQ,q触发时间服务器开始计时?/span>
3?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
Z充血模型的工作项引擎
Ҏ(gu)l用戯言Q大部分的业务操作都集中在对工作的操作上。常见的包括工作的提交、收回、委z、追加和退回。这些操作从pȝ设计的角度不仅涉及到工作(WorkitemQ对象内部状态的变化Q而且影响到流E执行引擎的调度以及相关的其他工作项对象状态?/span>
工作引擎的职责包括两部分。第一Q监听Q务节点实例的q入事gQ生成工作项实例。第二,处理上面提到的各U工作项操作?/span>
实现Ӟ工作生成器Ҏ(gu)d参与者的执行模式典型的分为四U情况:
竞争参与Q?/span>当有多个参与者参与该dӞ产生竞争Q谁先开始这工作,q谁负责完成该工作。此Ӟ工作生成器生成多个工作实例,在某个工作项完成时会l止其余工作V?/span>
序参与Q?/span>多个参与者按照指定的序完成该工作?/span>A完成之后?/span>B完成Q?/span>B完成之后再交l?/span>C完成。此Ӟ工作生成器生成多个工作实例,Ҏ(gu)序依次Ȁzd个工作项?/span>
共同参与Q?/span>多个参与者同时对工作q行处理。此Ӟ工作生成器生成多个工作实例ƈ全部ȀzR?/span>
决策Q?/span>存在多个参与者的情况下,工作生成器能够Ҏ(gu)一定的指标Q由数据分析Q例如h员的处理效率Q工作负载等{)和规则来军_该节点的参与者ƈ为其生成相应工作V这里涉及到法?/span>
对于工作系l而言Q各U流E实例对象都是充血模型。特定于各种工作Ҏ(gu)作的处理Q此时的工作对象亦设计为充血模型Q将业务逻辑装到领域模型里Q简化领域模型之间的交互Q省去频J的get/set。由领域模型再委zֈ具体的处理类里?/span>
Client->(Business Facade)->Domain Model->service->Data Access(DAO)
4?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
工作w动业务表单的业务集成方式
最l用户对d的处理,必然由工作项对应着某一业务表单。用户在工作列表里选择自己需要办理的工作,由工作项DC务表单?/span>
特定?/span>WEBpȝQ业务表单的D?/span>url完成。在程定义模型设计Ӟ?/span>url讄入节点属性,生成工作Ҏ(gu)此url保存在工作项对象属性里。点d作项详细信息时即打开?/span>urlQ完成到业务表单的导航。业务表单页面通常需要引入处理工作项逻辑的父面或者导入定制的js库,q些爉面或js库由工作品提供。这P对于业务表单~写Q工作流逻辑是透明的?/span>
一、什么是业务程
业务程是一个技?/span>术语Q它h准确的定义:有组l的zdQ?/span>怺联系Qؓ客户创造h(hun)倹{?/span>
q句话很好理解。甚臛_以说M企业的活动都是以业务ZU,以流EؓU烦串联h的。企业的规章制度、操作手册等都与业务程有着契合炏V?/span>
二、业务流E对于企业的意义
业务程对于企业的意义不仅仅在于对企业关键业务的一U描qͼ更在于对企业的业务运营有着指导意义Q这U意义体现在对资源的优化、对企业l织机构的优化以及对理制度的一pd改变。这U优化的目的实际也是企业所q求的目标:降低企业的运营成本,提高对市场需求的响应速度Q争取企业利润的最大化?/span>
三、业务流E也是一个体p?/span>
业务程通常的表现Ş式是程图(不是唯一形式Q,毕竟囑Ş是最易于理解的一UŞ式,但似乎我们太x于流E图本n而忽略了其他。除了流E图之外Q业务流E还应该包括目标和指导方针,q才是一个完整的业务程。在梳理业务使用业务程描述旉先要惛_的是该流E所要达到的目标Q能为客户创造什么h(hun)|q开业务目标或者说Ua为描qC务而描qC务是没有意义的。同时在制定业务程时也要考虑到该业务程的指导方针,同一个业务可能有很多U业务流E的描述形式Q具体哪一U是最合适的Q这里就必须有一个指导方针来q行U束?/span>
四、业务流E的特征
1、层ơ性、逐层抽象
业务程是有层次性的Q这U层ơ体现在׃至下、由整体到部分、由宏观到微观、由抽象到具体的逻辑关系?/span>
q样一个层ơ关pȝ合h们的思维习惯Q有利于企业业务模型的徏立。一般来_我们可以先徏立主要业务流E的Mq行q程Q其中包括了整个企业的大的战略)Q然后对其中的每Ҏ(gu)动进行细化,落实到各个部门的业务q程Q徏立相对独立的子业务流E以及ؓ其服务的辅助业务程?/span>
业务程之间的层ơ关pM定程度上也反映了企业部门之间的层ơ关pR不同层U的部门有着对业务流E不同的分理权限。决{层、管理者、用者可以清晰的查看C属和下属部门的业务流E?/span>
Z得所建立的业务流E能够更畅的运行,业务程的改q与企业l织l构的优化是一个相互制U、相互促q的q程?/p>
2、以Zؓ?/span>
l织中最重要的部分是人员的工作方式以及构成他们每日操作的工作程?/span>
人是业务程的驱动者,l织中的每一个h都会在业务流E中充当一个角艌Ӏ通过良好的业务流E,每一个h都会有自己清晰的职责Q要求具有良好的沟通协作意识和团队意识Q明自己在一个个业务程中所担当的角艌Ӏ?/span>
同时对于参与其中的业务流E,每个人员都要有自q反馈?/span>
首先Q每个h员都能查看到q些业务程Q他们需要充分理解这些业务流E、流E的业务意义和目的,q些业务程通过切合他们理解能力的方式(切合业务的图形、说明文字、相应的制度、规范、标准等{)得以展现?/span>
其次Q对于流E运行中存在的问题或瓉Q每个h员都要积极反馈(提出修改的徏议,或者在权限范围内直接修改)以促q流E的持箋改进Q业务流E的理和变动不仅仅是业务分析h员或理人员的职责,每一个员工都要参与其中,否则只有p|。管理h员和决策层更重要的职责是制定Z务流E的规则和约束,在这个规则和U束范围内,员工可以Ҏ(gu)变化的商业环境对业务程做出q速修改,q样不必{到领导了解情况后再做出决策从而失L会?/span>
3、对程q行效益的分?/span>
从企业投资者的角度来讲Q好的业务流E设计必然是能够Z业带来最高利润的设计。因此,对业务流E的效益分析是评价业务流E的一个重要方面。胦务数据是最关键的数据,但这U分析不一定完全是由数据支撑的Q有些是不能量化的,比如人员效率{等?/span>
五、业务流E管?/span>
良好的业务流E管理是保证企业灉|q营的关键(业务程理又何不是一U业务流E?Q?/span>
1、业务分?/span>
实际q也是业务流E管理最重要的部分。它需要对企业业务有着强大的分析能力,因ؓ业务分析对企业的q营有着重大的指导意义,只有具备了这L业务分析能力Q才能把握住企业q{的真实流E,而且q种分析能力往往带有Ҏ(gu)个行业的深刻理解和前L。没有异议,业务分析在于人,?/span>IT无关?/span>
2、业务流E的持箋改进
不仅仅是程理人员Q管理决{层Q根据运行效益的分析和商业环境的分析Ҏ(gu)E进行重整。还包括每个员工对其参与的流E的持箋反馈和持l改q。柔性的业务程?/span>
3、ITpȝ与业务流E的关系
ITpȝ与业务流Eƈ没有直接的关pR正?/span>06z?/span>SOA帖子里表辄Q?/span>soa95%以上的工作是在做业务程的分析解构和重整Q技术层面的支持只占5%不到。在落实到技术层面,你觉得一?/span>soa产品I竟应该包括些什么内容呢Q这些内容又能有多少是能够辅助大家对业务程q行分析和测试,对业务元素进行重整和再分配?如果你们真的有这个能力,你们觉得是在q里l箋开发Y件过苦日子,q是d拓商业咨询呢Q我的观Ҏ(gu)Q?/span>SOA很美好,但是一落地变成了丑。所谓的业务程理软g同理?/span>
可以q样理解Q业务流E管理是一个很大的命题Q?/span>ITpȝ通过信息化对它的子集q行支撑Q这里的ITpȝ包括的范围很q泛Q包括了所有的企业应用软gQ所有的企业应用软g都可以看作是对企业某部分的业务流E进行的描述Q。业务流E管理的核心在于业务程的分析解构和重整Q这Ҏ(gu)所有Y仉不可企及的,关键在于人。至?/span>BPMq是工作,它们本来有它们自己的适用范围Q硬要把它提升到业务程理的高度来宣传Q那q的和丑一P滑稽而可W?/span>
x下篇Q?/span>BPM是干什么的
收回是工作流参与者对自己“已办d”Q对已完成的工作)的一U操作,卛_与者主动对已办理过的工作项q行重新办理?/span>
Z么要收回Q?/span>
参与者完成Q务后Q发现自己办理有错误{情况后Q需要将此Q务收回重新办理?/p>
工作的参与方式
目前有四U方式:共同参与、竞争参与、顺序参与、基于角色的共同参与?/p>
下面会针对这四种方式q行讨论?/p>
工作Ҏ(gu)回模?/strong>
1、未触发下一节点的工作项的收?/strong>
卛_前Q务节点ƈ未完成,依旧处于执行状?/p>
1.1共同参与
如图Q在节点A未结束之前,workitem1、workitem2和workitem3正常完成后可以Q意收回。在只生一个workitem的情况下Q不存在未触发下一节点的收回情c?/p>
1.2序参与
如图Q?/span>workitem1?/span>workitem2?/span>workitem3序完成Q?/span>workitem1?/span>workitem2{收Q包括挂起和手工l止Q前可以收回Q同Pworkitem2?/span>workitem3{收Q包括挂起和手工l止Q前也可以收回?/span>在只产生一?/span>workitem的情况下Q?/span>不存在未触发下一节点的收回情c?/span>
1.3竞争参与
因ؓ只会产生一?/span>workitemQ该workitem完成后会立刻触发下一节点Q所以不存在未触发下一节点的收回情c?/span>
1.4Z角色的共同参?/span>
?/span>1.1相同?/span>
2、已触发下一节点的工作项的收?/span>
2.1共同参与
问题1Q多个工作项时谁可以执行收回操作Q?/span>
workitem1?/span>workitem2?/span>workitem3都可以执行收回操作。第一个工作项的收回将会导致节?/span>B实例的删除,同时节点A重新恢复执行状态?/span>
问题2Q节?/span>B处于什么状态节?/span>A的工作项可以执行收回操作Q?/span>
?/span>A触发的节?/span>B处于正在执行的状态,节点B所产生的工作项Q?/span>
a共同参与 工作均未签收、挂h手工l止
b序参与 W一个工作项未签收、挂h手工l止
c 竞争参与 工作均未签收、挂h手工l止
d角色 同共同参?/span>
问题3Q工作项收回产生的媄响?
节点A重新执行Q收回的工作w新执行。节?/span>B重新恢复未触发状态,B所产生的工作项全部删除?/span>
2.2序参与
问题1Q多个工作项时谁可以执行收回操作Q?/span>
workitem1?/span>workitem2?/span>workitem3Ҏ(gu)序可以依次执行收回操作?/span>
2.3竞争参与
情况单,只有一个工作项Q所以可以直接收回?/span>
2.4Z角色的共同参?/span>
?/span>2.1
工作收回模?/strong>
后箋触发节点只能是h工节点(可以是多个,臛_一个)Q否则不支持收回。目前不支持父子程之间的收回?/p>
一个典型的同步汇聚情况Q?/span>
节点1首先执行完毕Q但是因为是同步汇聚Q所以它不会触发实际的流转;而节?/span>2的完成则会触发节?/span>3的执行。在q种情况下,节点2的工作项可以执行收回操作Q而节?/span>1的工作项因ؓ后箋没有触发节点而不能收回?/span>
回退QRollback WorkItemQ?/span>
回退是工作流参与者对自己“待办d”Q实际是对工作项Q的一U操作,卛_与者主动回退待办d列表中的d到已l执行过的h工节炏V?/p>
Z么要回退Q?/span>
参与者接受Q务后Q发C应由自己办理此Q务或以前的执行者办理有错误{情况后Q需要将此接受的d回退l以前某个节点的执行者重新办理?/p>
回退模式
回退的情况实际上是非常复杂的Q其中包括了参与者的重新选择以及回退的条件判断等{。这里先列出常见的回退模式Q其实也是我们支持的模式Q?/p>
串行
q种情况最为简单,后箋节点可以回退到前lQ意h工节炏V回退后,节点重走?/p>
分支
q种情况也相对简单,实际执行的分支上的节点可以回退到前lQ意h工节点(不区分主支和分支Q。同PL上的节点也可以回退CQ意实际执行的分支上的节点?/p>
可能的问题:多次回退后的回退节点选择。例如:W一ơ流E经q节?、节?到达节点5Q节?可以回退到节?、节?和节?的Q意一个,此时节点5回退到节?Q节?重走Q这一ơ流E改为经q节?到达节点5Q节?回退时如何选择回退节点Q此时的{略是以最q实际执行的分支为准Q即节点5只允许回退到节?和节?Q不允许回退到节?和节?。(抹去记忆Q?/p>
q发
对于q发的情况,分支节点只允许在分支的节炚w回退?/p>
同理Q主支节点也只允许在L的节炚w回退?/p>
多实例汇?/p>
在这U情况下Q节?会?个实例,实际相当于lƈ发。节?Ҏ(gu)具体哪个节点触发的它而生回退节点。同时不允许回退到节?以及前箋的节点去?/p>
子流E?/p>
支持子流E到父流E的回退Q也支持父流E到子流E节点的回退。需要注意的是子程节点有可能生多个子程实例Q在q种情况下不支持父子程之间的相互回退?/p>
回退节点的参与者选择
默认{略是由原先节点的实际参与者重新处理,比如节点2回退到节?Q则节点1的实际参与者重新处理该节点d。这也符合大多数实际的业务场景?/p>
在节点Q务竞争参与的情况下,提供另一U策略,卌人员重新竞争?/p>
回退的条件判?/strong>
对于多hQ或者多部门Q用P参与的工作项Q提供不同的回退{略
L人回退卛_退Q剩余工作项手工l止
最后提交h回退才回退
程定义期定义该{略?/span>
另外程定义时提供节点可回退列表Q由用户在定义期对可回退的节点进行限制?/span>
关于业务补偿
业务补偿是一个很重要的概念,在回退的情况下需要相应的回退部分业务操作。这里由引擎提供l一的接口,q回回退路径Q由客户自定义代码进行匹配处理?/span>
关于实现
很多工作引擎通过程定义时绘出回退U来昑ּ的支持回退Q这U实现在业务复杂的情况下会造成程囄异常烦琐Q但是比较清晎ͼ实现比较Ҏ(gu)。隐式实现相比而言优点更多?/span>
一、流E实例的状?/span>
状态分?/span>5U:实例化、执行中、挂赗手工结束、正常结束?/span>
状态的变迁如下图:
二、节点实例的状?/span>
状态分?/span>5U:实例化、执行中、挂赗手工结束、正常结束?/span>
状态的变迁如下图:
三、具体节点的状?/span>
l分Q?/span>
A、h工节炏V等待节?/span>
q两个节点被触发后存在一个执行等待的q程Q所以可以被用户直接挂v和手工结束。h工节点的挂v意味着所有未完成工作的挂vQ同时相应时间服务的旉计算的挂赗手工结束会使流E蟩q该节点Q所有工作项手工l束Q,l箋往后流转?/span>
B、开始节炏V结束节炏V分支节炏V自动节?/span>
q些节点的特点在于被触发后立L行和{Q所以不会存在挂起和手工l束的状态?/span>
C、ƈ发节炏V汇聚节?/span>
q发节点和汇聚节点不存在挂v的状态,同时不能被用L接手工结束,它们的状态受程实例状态和相关节点实例状态的影响?/span>
q发节点和汇聚节点的情况复杂一些,分模式讨?/span>
?/span>1
1、同步汇聚(?/span>1Q?/span>
Ҏ(gu)情况触发节点0、节?/span>1、节?/span>2中的一个或多个Q汇聚节点等待所有实际触发的节点完成后再执行{。中间汇聚节点只会生一个实例?/span>
1.1、正常流转时的处理策?/span>
当汇聚节Ҏ(gu)被触发时Q即节点0、节?/span>1、节?/span>2都未执行l束Q,q发节点处于执行状态,一旦汇聚节点被触发Q即节点0、节?/span>1、节?/span>2有一个执行结束)Qƈ发节Ҏ(gu)常结束ƈ且汇聚节点处于执行状态,所有ƈ发出的节点实例执行结束后Q汇聚节Ҏ(gu)常结束,程l箋{?/span>
1.2、用h赗手工结束相兌点的处理{略
1.2.1、汇聚节Ҏ(gu)ȀzL
节点0、节?/span>1、节?/span>2的挂起和恢复执行不会影响q发节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2的Q一手工l束都会触发汇聚节点Qq发节点正常l束Q如果所有ƈ发的节点实例都结束(包括手工l束和正常结束)Q汇聚节Ҏ(gu)常结束,触发程{?/span>
1.2.2、汇聚节点已ȀzL
节点0、节?/span>1、节?/span>2的挂起和恢复执行不会影响汇聚节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2的手工结束会影响汇聚节点的状态,每个节点实例的手工结束会引v汇聚节点的判断,如果所有ƈ发的节点实例Q包括正常结束和手工l束Q都l束Q汇聚节Ҏ(gu)常结束,触发程{?/span>
1.3、用h赗手工结束流E的处理{略
1.3.1、汇聚节Ҏ(gu)ȀzL
程的挂起和恢复执行不会影响q发节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2会被全部挂v或恢复;程的手工结束会引v所有节点的手工l束?/span>
1.3.2、汇聚节点已ȀzL
程的挂起和恢复执行不会影响汇聚节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2未执行结束的实例会被全部挂v或恢复;程的手工结束会引v所有节点的手工l束?/span>
2、nOutOfM汇聚Q图1Q?/span>
Ҏ(gu)情况触发节点0、节?/span>1、节?/span>2中的一个或多个Q汇聚节点等?/span>N个实际触发的节点完成后即执行{Q?/span>N>0?/span>N<MQ?/span>M为实际触发的节点个数Q,?/span>N<=0?/span>N>=M的情况下即ؓ同步汇聚。中间汇聚节点只会生一个实例?/span>
2.1、正常流转时的处理策?/span>
当汇聚节Ҏ(gu)被触发时Q即节点0、节?/span>1、节?/span>2都未执行l束Q,q发节点处于执行状态,一旦汇聚节点被触发Q即节点0、节?/span>1、节?/span>2有一个执行结束)Qƈ发节Ҏ(gu)常结束ƈ且汇聚节点处于执行状态,N个ƈ发出的节点实例执行结束后Q汇聚节Ҏ(gu)常结束,程l箋{Q?/span>M-N的节点实例被手工l束?/span>
2.2、用h赗手工结束相兌点的处理{略
2.2.1、汇聚节Ҏ(gu)ȀzL
节点0、节?/span>1、节?/span>2的挂起和恢复执行不会影响q发节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2的Q一手工l束都会触发汇聚节点Qq发节点正常l束Q如?/span>N个ƈ发的节点实例都手工结束,q发节点正常l束Q触发汇聚节点,汇聚节点正常l束Q触发流E流转,M-N的节点实例被手工l束?/span>
2.2.2、汇聚节点已ȀzL
节点0、节?/span>1、节?/span>2的挂起和恢复执行不会影响汇聚节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2的手工结束会影响汇聚节点的状态,每个节点实例的手工结束会引v汇聚节点的判断,如果N个ƈ发的节点实例Q包括正常结束和手工l束Q都l束Q汇聚节Ҏ(gu)常结束,触发程{Q?/span>M-N的节点实例被手工l束?/span>
2.3、用h赗手工结束流E的处理{略
2.3.1、汇聚节Ҏ(gu)ȀzL
程的挂起和恢复执行不会影响q发节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2会被全部挂v或恢复;程的手工结束会引v所有节点的手工l束?/span>
2.3.2、汇聚节点已ȀzL
程的挂起和恢复执行不会影响汇聚节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2未执行结束的实例会被全部挂v或恢复;程的手工结束会引v所有节点的手工l束?/span>
3、L别汇聚(?/span>1Q?/span>
?/span>nOutOfM汇聚的特例,N=1
4、多实例汇聚Q图2Q?/span>
?/span>2
Ҏ(gu)情况触发节点0、节?/span>1中的一个或多个Q节?/span>0和节?/span>1L一个执行结束后都会触发汇聚节点产生一个新的实例,汇聚节点实例紧接着触发节点2Q节?/span>2也会产生多个实例?/span>
4.1、正常流转时的处理策?/span>
当汇聚节Ҏ(gu)被触发时Q即节点0、节?/span>1都未执行l束Q,q发节点处于执行状态,一旦汇聚节点被触发Q即节点0、节?/span>1有一个执行结束)Q汇聚节点会紧接着触发节点2Q汇聚节Ҏ(gu)常结束。所有ƈ发出的节点实例执行结束后Qƈ发节Ҏ(gu)常结束?/span>
4.2、用h赗手工结束相兌点的处理{略
节点0、节?/span>1的挂起和恢复执行不会影响q发节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1的手工结束会影响q发节点和汇聚节点的状态,每个节点实例的手工结束会引v汇聚节点产生新的实例q触发节?/span>2Q同时会引vq发节点的判断,如果所有ƈ发的节点实例都手工结束,q发节点正常l束?/span>
4.3、用h赗手工结束流E的处理{略
程的挂起和恢复执行不会影响q发节点的状态(依旧处于执行状态)Q节?/span>0、节?/span>1、节?/span>2会被全部挂v或恢复;程的手工结束会引v所有未l束节点的手工结束?/span>
5、隐式结束,没有汇聚节点与ƈ发节点对应(?/span>3Q?/span>
?/span>3
所有节点结束时Q正常结束或手工l束Q,q发节点正常l束。流E的手工l束会引h有未l束节点的手工结束?/span>
四、流E实例状态变化对节点实例状态造成的媄?/span>
1、流E实例的挂v
Ac节Ҏ(gu)PB?/span>Cc节点不受媄响。同时在程实例恢复执行之前Q?/span>Ac节点不允许用户直接恢复执行?/span>
2、流E实例的手工l束
所有节点全部手工结束?/span>
五、节点实例状态变化对程实例状态造成的媄?/span>
隐式l束的情况下Q节点的手工l束或正常结束都会触发流E的判断Q如果所有的节点都已l束则流E结束?/span>
先来看看具体的应用场景?/span>
单表增删Ҏ(gu)
q是最单的情ŞQ也没有程Q对q个情Ş不加讨论。但是这里会提到表单引擎Q?/span>VB里的数据控g非常的易用,没有POQ没?/span>DAOQ也没有ServiceQ直接与数据库字D进行绑定。我们的表单引擎也可以采用这U方式?/span>
支持表单控gQ输入框、文本框、下拉框{)的拖拽,整个表单与数据库表l定?/span>
表单控g与数据库字段的绑定?/span>
单表业务+程
比上面的情况E微复杂一点点Q也是要在业务里引入流E,其实q也是现在工作流引擎应用最多的地方Q比如说政府OA里的收文、发文?/span>
q里只需要将表单与流E进行绑定,表单引擎的处理方式不变,依然是直接与数据库表q行l定。表单负责对数据库里的业务数据进行展玎ͼ工作则负责推动q些数据在业务意义上状态的转换Q互不媄响,q在需要的时候在自动节点上对q些数据q行相应的业务处理?/span>
关于表单权限。这个也是表单与工作进行绑定时所必须考虑到的问题。其实只是需要在表单引擎里引入权限角色的概念Q每个角色对应于一U权限,q种权限具体说来是表单里每个字D늚可见、可~辑{等。然后在人工节点定义时指定表单权限角色即可。这样也实现了流E与表单权限一定程度上的解耦?/span>
其实q有一U更方便的方式,表单直接与人工节点q行l定Q每个h工节点对应于不同的表单?/span>
复杂一点,多表兌的情?/span>
复杂一点的情况是业务往往是多表的兌。这需要对表单引擎做出扩展Q让它可以根据关联字D对兌表做出查询,得到兌表的设计l构Ql映。这让我惌v?/span>ORMQ这里很?/span>FRM的意思在里面。其实对于常用的兌查询往往有通用的组件可用,例如Ҏ(gu)userid渲染出用户名Q根据数据字典的id兌渲染出相应的|oa里的正文、附件、印章等{?/span>
程跨越多个业务
程需要跨多个业务,一个典型的程如下Q?/span>
会议审批会涉及到两张业务表:会议室用表Q会议记录表。在会议甌和领导审批节点,最l用h开的都是会议申L表单Q对应于会议记录表,对该表进行操作。但是流E运行到会议室管理员安排会议室的节点Q该节点最l用户不仅需要看C议申L表单同时q要看到会议室用情늚表单Q如果有I闲的会议室Q用L记操作会议室使用表,然后通知甌者;如果没有I闲的会议室Q则不用登记直接通知甌者。这个过E中跨越了两个业务,分别是会议室理和会议管理。表单在各个节点也是不同的?/span>
q其实对工作引擎提Z比较高的要求。例如如果流E已l结束,会议得到批准Q但甌者突然有事要改变会议旉怎么办?回退。这里的回退无疑需要有业务的补偿,例如要删除会议室的相兌录?/span>
应用集成
一个流E不仅会跨越多个业务Q也会跨多个系l。这里的应用场景很多Q重要的是要d他系l抓取数据和操作数据Q仅仅靠数据库表对表单的映射满不了需求?/span>
对工作流引擎做出改进Q与前面相比Q需要由引擎来完成对其他pȝ服务的调用。这里一个很重要的蝲体就?/span>XML。首先要定义交换数据所用的XML schemeQ然后将q个XML scheme再与表单引擎做出映射。实际执行时Q工作流的自动节点会在h工节点前调用其他pȝ的服务,按照XML scheme数据{换ؓW合定义?/span>XMLQ在紧接着的h工节炚w给表单引擎Q表单引擎渲染。修Ҏ(gu)据也是同Lq程Q表单引擎将处理后的数据?/span>XMLq回Q工作流再次做出转换Q调用服务的修改功能?/span>
上面五种都是比较常见的应用场景,理想的情况下Q开发方式应该是q样的:d应用程à定义程表单à表单与数据库q行映射àҎ(gu)E进行业务仿?/span>à完成开发。问题是q样的:你的表单引擎是否_强大Q表单与后台是直接用SQLq行交互的,也就?/span>Transaction Script模式Q没有业务对象,对于复杂业务逻辑如何处理Q如何用规则引擎来解决业务逻辑的问题?权限如何以一U?/span>AOP的方式对数据操作q行横切Q?/span>
呵呵Q纯属个?/span>YY?/span>
对于当前的工作流应用来说Qh工节Ҏ(gu)疑扮演着一个非帔R要的角色。因为无论是传统的协同办公系l还是越来越多的企业应用Q都需要有人参与到具体的流E中来。这文章着重分析工作流应用中h工节Ҏ(gu)涉及到的参与者模式以及与此关联的工作Ҏ(gu)式,最后会提供部分的解x案作为参考?/span>
先简单说说什么是人工节点?/span>
人工节点的概忉|与自动节点相对的。顾名思义Qh工节点就是需要有人参与的节点Q在实际程中,它体现在产生׃h完成的工作项以及׃h军_一些决{变量,q些决策变量会对程的运行生媄响(例如分支的选择{等Q。自动节点则是由工作引擎自p用完成,不需要h的参与,通常是执行定制的业务操作。相比较而言Qh工节Ҏ(gu)多的应用在管理流E里Q而自动节Ҏ(gu)多的则是应用在企业业务流E里?/span>
人工节点的职责有三个Q第一是决定该节点的参与者;W二是根据参与者生成需要h来处理的工作;最后是当工作项被参与者处理完毕时Q它?yu)l触发流E的{。参与者处理工作项时可以处理相应的业务和设|流E决{变量?/span>
下面我们按照这三个职责分别对h工节Ҏ(gu)涉及到的参与者模式和工作Ҏ(gu)式进行分析?/span>
1?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 军_参与者模?/span>
换句话说是军_该节点的参与者,q里有两U模式:引擎自动获取和最l用h定?/span>
1Q?/span>1引擎自动获取
所谓引擎自动获取就是由引擎在运行期计算实际的节点参与者,不需要最l用L参与。这个计基于流E定义时对该节点参与者的定义?/span>
Q?Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
直接指定人员、部门或角色
q种情况最单,也最直接Q用户定义节Ҏ(gu)直接在组l用h里选定人员、部门或角色Q然后在q行期根据定义执行与或者是或的q算。大多数的工作流引擎都支持这U模式。但很明昑֮也存在着很大的局限性,它是静态的Q一旦流E定义完毕参与者也p着固定下来Q运行期的Q何变化都不会对参与者造成影响Q一个很单的需求,请假程Q节点的参与者需要是当前甌者的部门领导Q因为申误在定义期是不确定的Q所以根本无法指定节点的参与者,所以这U模式远q满不了用L微复杂一点的需求?/span>
Q?Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
调用用户定制的计参与者代?/span>
q种情况通常是由引擎提供一个接口或是父c,用户需要实现或是承这个接口或父类Q然后实现相应的Ҏ(gu)。这个方法通常会传递进一个执行上下文的参敎ͼ用户代码通过q个上下文可以访问到当前程实例的信息,例如当前节点状态,工作变量等{,然后用户可以Ҏ(gu)实际业务和当前流E实例信息进行逻辑计算Q最后返回一个参与者的ID集合。对于上一个模式里提到的计当前申误部门领导的例子Q这个模式实现v来非常简单,首先获得当前甌?/span>IDQ然后在Ҏ(gu)q个ID扑և该申误部门再扑և该部门领导即可?/span>
实际程q行到该节点׃调用用户自己定制的计参与者的代码Q方法返回的参与?/span>ID即作节点的实际参与者?/span>
q种模式对于工作引擎的实现而言最为简单,因ؓ它把最大的复杂性都抛给了用Pq户代码来计算实际的参与者。实际上很多开源的工作引擎采用的都是q种方式Q例?/span>JBPM。但是这U方式给用户带来最大灵zL的同时也带来了复杂和烦琐。特别是当面对一个数量巨大的程需求时Qؓ每一个流E的每一个h工节炚w定义一个参与者计类是让人头疼的。再加上现在业务的敏P业务里的改变要迅速反馈到程的定义里Q让最l用h~写或修改这个参与者计类不现实也不可能。补充一下,q也是用户在考虑采用开源的工作引擎还是商业工作流引擎旉要着重考虑的一个方面?/span>
Q?Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
指定前箋节点的参与?/span>
实际上是用户在节点定义时指定参与者ؓ前箋某个节点的参与者,当流E运行到该节点,引擎会自动获取所指定的前l节点的参与者作节点的实际参与者?/span>
q个模式实现hq不困难Q大多数商业工作引擎都对该模式q行了支持。它能够满用户的部分特定需求?/span>
Q?Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
更ؓ复杂的情?/span>
用户的需求永q是复杂的,引擎所要做得就是尽量降低这U复杂性,程的变化要能够q速跟上业务的变化。考虑下面两种E微复杂一点但是又很常见的需求。需求一Q参与者ؓ当前甌者的部门领导且职位ؓ副总;需求二Q参与者需要是试部的所有女同事。这两种需求模?/span>1?/span>3都不能满I2可以Q但是正如提到的那样Q模?/span>2可能会非常的烦琐Q不能适应业务的敏捗其实这里的复杂性主要体现在Q?/span>1、这里的参与者可能是q行期决定的Q?/span>2、参与者的限制条g可能非常多,而这些条件不是简单的部门、角色或职位所能描q的?/span>
对于一般的工作引擎而言Q它们都会选择模式2的实玎ͼ让用戯己实现逻辑。实际在后面的部分解x案里Q我们会看到更ؓ好一点的实现方式?/span>
1.2最l用h?/span>
q行期由最l用h军_节点的参与者。这也是中国国情所独有的特艌Ӏ这U模式最为常见的是用户提交工作Ҏ(gu)的提交页面,用户在该面上选定下一节点Q多数分支用户选定Ӟ和下一节点的参与者。这U模式本wƈ不困难,问题在于在提交页面需要给用户提供一个参与者的选择范围Q让用户q行选择。而关于这个选择范围Q则又回到前面所提到的引擎自动获取的模式Q这个范围同h需要引擎计的。于是又回到了刚刚讨的四U模式?/span>
2、参与者执行模?/span>
现在Q已l获得了节点的参与者。引擎下一步将会根据这个参与者生成工作项Q注意,q里的参与者可能是一个hQ也可能会是一个h员范_卛_个hQ。于是就产生了参与者的执行模式Q也可以理解为工作项的生成模式?/span>
2.1竞争参与
当有多个参与者参与这个节Ҏ(gu)׃产生竞争参与q个模式。同样一个工作,A可以完成Q?/span>B也可以完成,于是׃生竞争,谁先开始这工作,q谁负责完成该工作?/span>
2.2序参与
多个参与者按照指定的序完成该工作项?/span>A完成之后?/span>B完成Q?/span>B完成之后再交l?/span>C完成?/span>
2.3同时参与
多个参与者同时对工作q行处理Q所有参与者均完成后,程l箋向后{。这个模式其实比较复杂,因ؓq里同时涉及C个完成规则:是所有参与者均完成工作后程{Q还是有其他规则Q例如完?/span>2个工作项卛_{Q完?/span>80%的工作项卛_{。稍候会讨论到?/span>
2.4负蝲均衡
q也是一个常见的需求。这工?/span>A?/span>B都可以完成,但是A目前?/span>10个待办工作项Q?/span>B只有2个待办工作项。于是用h望该工作交由B来完成。这里需要实C个简单的负蝲均衡。其实这U情况只是智能决{的一U最单的情况Q所谓智能决{是指系l能够根据一定的指标Q由数据分析Q例如h员的处理效率Q工作负载等{)和规则来军_该节点的参与者?/span>
3?/span>工作完成模?/span>
q个模式在参与者执行模式ؓ同时参与时有效。在说到q个模式之前Q先单说说工作项可能存在的几U特D状态,q些状态包括挂赗h工终止和委派。挂起就是工作项暂时停止执行Q挂起会影响到流E的{Q会D程的挂赗h工终止则是h工手动改变该工作的状态,使该工作终止执行,q个人通常会是理员。h工终止也会对程{产生影响Q当除去该工作项之外的所有工作项都完成时Qh工终止该工作会触发程的流转。委zְ是将该工作项委派l他人完成,同时该工作项也就l束了。h工终止和委派是工作项l束的特D状态?/span>
3.1全部完成
当所有工作项都结束时触发节点的结束和程的流转?/span>
3.2完成规定的个?/span>
节点定义时指定工作项必须完成的个敎ͼ当完成的工作达到这个指定的个数时触发节点的l束和流E的{?/span>
3.3完成规定的百分比
节点定义时指定工作项必须完成的百分比Q当完成的工作项占所有工作项的比例达到这个指定的癑ֈ比时触发节点的结束和程的流转?/span>
其实q里很明昄可以看出不管是所谓的参与者执行模式还是工作项完成模式不过都是一定的规则Q既然是一定的规则那必然就限定了应用的灉|性,用户能否自定义规则?Ҏ(gu)业务灉|C改规则?规则引擎+DSL应该是一个不错的选择?/span>
%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;也就是把%AXIS_LIB%下所?/span>JAR文g都导?/span>
三、实验一?/span>
?/span>%AXIS_HOME%\webapps下找?/span>axis文g夹,其整个拯?/span>%TOMCAT_HOME%\webapps下,启动
Tomcat,打开览器访?/span>http://localhost:8080/axis/Q出C下页面说明你配置成功了。很单吧Q)
四、发布我们的W一个程?/span>
W一个程序简单的q回HELLO WORLDQ?/span>
public class HelloWorld {
public String sayHello()
{
return "HELLO WORLD!";
}
}
我们的第一U发布方式:
?/span>HelloWorld.java拯?/span>%TOMCAT_HOME%\webapps\axis下,然后其改名?/span>HelloWorld.jws,q样AXISp然将其发布了。现在写个客LE序讉K一下:
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.rpc.ParameterMode;
public class TestClient
{
public static void main(String [] args) throws Exception {
String endpoint = "http://localhost:" +"8080"+ "/axis/HelloWorld.jws";//指明服务所在位|?/span>
Service service = new Service(); //创徏一个Service实例Q注意是必须的!
Call call = (Call) service.createCall();//创徏Call实例Q也是必ȝQ?/span>
call.setTargetEndpointAddress( new java.net.URL(endpoint) );//为Call讄服务的位|?/span>
call.setOperationName( "sayHello" );//注意Ҏ(gu)名与HelloWorld.java中一PQ?/span>
String res = (String) call.invoke( new Object[] {} );//q回StringQ没有传入参?/span>
System.out.println( res );
}
}
我的试是在jbuilder2005中,注意目中要导入其自带的AXIS包(当然应该把其?/span>JAR文g替换一下)Q可以看到程序返回了 "HELLO WORLD!"
可以看到?/span>AXIS里发布服务其实是一件很Ҏ(gu)的事Q这是因个服务很单的原因Q)下面我们介绍W二U发布方式,q是常用的?/span>
我们的第二种发布方式Q?/span>
1、将HelloWorld.java~译?/span>HelloWorld.class,攑ֈ%TOMCAT_HOME%\webapps\axis\WEB-INF\classes?/span>
2、在%TOMCAT_HOME%\webapps\axis\WEB-INF下新?/span>deploy.wsdd文gQ即SOAP服务发布描述文g
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="HelloWorld" provider="java:RPC">
<parameter name="className" value="HelloWorld"/>
<parameter name="allowedMethods" value="sayHello"/>
</service>
</deployment>
?/span>DOS下{换目录到%TOMCAT_HOME%\webapps\axis\WEB-INFQ命令:
你会发现目录下多了一?/span>server-config.wsdd文gQ这是AXIS的配|文Ӟ以后所有的服务发布描述都会在里面找到。(当然Q你可以直接修改它,不用再写deploy.wsddQ然后打开览?/span>http://localhost:8080/axis/servlet/AxisServletQ你׃看到你的服务已发?/span>
同样用客LE序讉K一下:Q注意和上边的差别!Q)
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class HelloClient
{
public static void main(String [] args) throws Exception {
String endpoint = "http://localhost:" +"8080"+ "/axis/services/HelloWorld";//注意Q差别仅仅在q里Q!
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName("sayHello" );
String res = (String) call.invoke( new Object[] {} );
System.out.println( res );
}
}