E-State:企业级状态机 - 来自ROOM的框架

正在愁怎么用状态机整理项目里的通信,找到这篇。参照一下

整理的时候用:状态表

演示的时候用状态图
实现的时候?想把状态机的实现和业务逻辑分开
应该是状态机,facade,逻辑。逻辑独立与状态机,通过facade组合进去


E-State和工作流

我在前面的文章“状态机与工作流(State Machines and Workflow)”(WLDJ,卷3,第1期)中讨论过工作流和状态机,它们是面向流程的应用程序的补充实现策略。 状态技术是对许多业务流程中所采用的“里程碑”技术所做继承的强大抽象。另一方面,工作流 - 这里特指BEA WeblogicIntegration的Business Process Modeler(BPM)组件 - 提供了重要的企业级服务,例如外部系统集成、人员工作列表(worklist)和任务管理,事件和计时器,以及XML消息处理。在前面的文章中指出过,混合的状态-工作流解决方案有以下几个部分:

1.  状态机框架,由以下部分构成:
- 状态模型: 一套状态和转换,在XML文档中表达。
- Actor数据库: 主角(actor)是指具有状态的实体。Actor的状态由状态机保存在数据库里。
- 状态机引擎: 把事件插入Actor的状态模型中,并相应地更新状态。它还会在进入、退出状态或者发生转换时,调用用户自定义动作类。
- 动作类: 用户自定义的Java类,负责响应某种状态的进入或退出,或者某个Actor在特定状态模型下执行过滤形态。

2. BPM工作流:负责接收事件,然后把事件插入状态机。

3. BPM工作流:设置计时器,在时间用尽的时候把超时事件插入状态机。

4.  BPM工作流:某一状态动作调用该工作流,给它分配一个工作列表任务或与外部系统交互。

E-State 是第一部分即状态机框架的参考实现。本文来讨论状态机的体系结构。

E-State 体系结构

方法学

E-State的状态模型基于实时面向对象建模(Real-time Object-Oriented Modeling -ROOM) 的方法。ROOM 的状态图是层次结构的,也就是说每个状态可以拥有子状态。这个主意很简单,效果却异常强大。 从人类思维的角度来看,平面状态模型无法进行扩展。当状态和转换的数量增长时,平面模型就会变得难于理解。而层次状态模型则可以分部分考察,每一部分理解起来相对就变得简单了。例如,考虑图 1。

 

在这个模型里,转换 ab 会使状态 a1a2 变成状态 b; 而转换ac 会使状态从a1a2 变成 c。所有状态的转换toC 会使状态变成c。 在状态a1里的转换 ba 会形成新的状态 a。初始状态是 b。状态从 a1变为a2时,要经过转换a1a2,从 a2 变为a1时,要经过a2a1。转换ca把状态引到一个选择点:如果最后的状态是a1,就变成a1,否则就变成a2

同样的场景,用层次结构来表示,理解起来就容易多了,如图2所示:

E-State:企业级状态机 - 来自ROOM的框架_第1张图片

首先,超级状态 a被细分为状态a1a2(图2中的右图);这样整个系统的状态图(图2中的左图)变得更简洁。从状态的高最层来看,转换abba只是在状态ab之间转换;但是在状态 a里,可以看到 ba 指向子状态a1,而 ab则来源于a1。 转换aca1a2 开始,指向c;转换 cac开始,指向 状态a的最后一个子状态。另外,转换toC不象图1中那样,要从每个状态来开始;来自最高层状态的非扩展转换点toC 的事件指向状态c,就可以表示需要的行为。

作为层次结构设计的成果之一,ROOM提供了二个强大的特性:组转换和历史恢复。所谓组转换是指:针对指定状态发生的转换,不论指定状态处在什么子状态当中;转换ac 把状态从 a 变为 c,不论状态a的子状态是a1还是 a2历史恢复 就是变回指定状态最近的子状态;转换ca 把状态 c 变回 a最近的子状态.

可以选择的方法还有UML和Petri-nets,它们都支持层次结构。

引擎

E-State的核心是一个无状态的会话Enterprise JavaBean (EJB),它被称为状态机(StateMachine),如图3中的阴影部分所示。

E-State:企业级状态机 - 来自ROOM的框架_第2张图片

StateMachine EJB被配置成指向具体的状态模型,使用XML文件来进行配置,配置文件中包含以下内容:

·一组状态和一组转换;

·唯一的命名空间,唯一命名空间有助于多重部署,稍后介绍。

·Java “动作”回调类的名称,状态机处理事件时,调用回调类。

EJB把模型用于“Actor”。在ROOM方法中,Actor指的是一个“活动”对象,状态模型最好地描述了这个对象的行为。

(在 ROOM里,活动对象拥有自己的控制线程,以及一组自己的入站、出站消息接口。E-State里Actor的概念更严格) 在 E-State里,Actor是拥有状态的实体,例如一个保险索赔。在一个模型里,从一个状态到另一个状态的转换,反映了Actor的状态变化;例如,索赔可能处在等待状态,激活状态,或者空闲状态。 E-State 有三个表负责跟踪Actor的状态,这三个表是 Actor(主角)、Actor_Property(主角属性)和 Actor_State(主角状态),还有对应的实体 EJB (Actor,ActorProperty,和 ActorState) 来表示这三个表,如图3所示。StateMachine EJB 某种程度上可以看作这些实体EJB的一个层面(facade)。StateMachine EJB的Actor管理方法有: createActor(),getCurrentState(),getChildState(), getActorProperty(),getActorProperties() 和 setActorProperty()。

状态机余下的方法 (startMachine() 和 injectEvent()) 形成了状态机引擎,驱动着Actor的状态变化。实际上,startMachine()只是调用 injectEvent(),给它传递了一个特殊的“初始化”事件,由injectEvent()执行转换操作,转换操作的起点是模型中每个状态的初始转换点。所以,injectEvent() 方法是状态机的核心,由它来驱动业务流程的动作前进。这个方法可以调用用户自定义动作类,从而实现模型中所定义的状态行动(StateAction)接口。动作类的功能是将重要的状态机事件通知客户,并向客户请示逻辑决策。在表1里列出了动作类的方法。

表1  动作类的方法

方法

动作

OnStateEnter

通知进入了一个状态

OnStateExit

通知退出了一个状态

OnTransitionExecute

通知执行了一个转换。如果方法返回真,则允许该转换发生,如果为假,则阻止转换(在ROOM的概念里,称为警卫(guard))

Choice

要执行选择点决策的请求。返回值为真或假,控制着状态模型里控制分支的流转方向。

在保险索赔的例子里,动作类启动工作流,执行与任务相关的工作或者清理工作,或者启动计数器。在 WebLogicIntegration 7.0里,由BPM 的API启动工作流。在In WebLogicIntegration 8.1里,则用Web服务调用工作流。

表2里归纳了StateMachine EJB的方法。

表2 StateMachine EJB的方法

方法

动作

CreateActor

在Actor表中为StateMachine EJB代表的模型建立一个新记录

GetCurrentState

取得StateMachine EJB代表的模型的Actor的当前叶子状态

GetChildState

取得StateMachine EJB代表的模型的Actor的指定状态的当前子状态

GetActorProperty

取得StateMachine EJB代表的模型的Actor的指定属性值

SetActorProperty

设置StateMachine EJB代表的模型的Actor的指定属性值

GetActorProperties

取得StateMachine EJB代表的模型的Actor的名称、类型和每个属性的值

StartMachine

执行模型里的每个状态的初始化转换,启动StateMachine EJB代表的模型的Actor的状态模型

InjectEvent

把指定事件插入StateMachine EJB代表的模型的Actor的状态模型里

在保险索赔的例子里,插入器(Injector)工作流调用状态机的 injectEvent()方法。在WebLogic Integration 7.0里,工作流使用一个业务操作来调用这个方法,而在 WebLogic Integration 8.1,则用EJB控件来完成。

数据库架构

图4显示了保持Actor持久状态信息的表结构。.

E-State:企业级状态机 - 来自ROOM的框架_第3张图片

在主表 Actor里,保存了特定 模型类型的Actor的当前状态。当前状态是指Actor目前所处的叶子状态。这个表的主键由Actor的唯一标识符和它的模型命名空间组合而成的。一个Actor可能在多个 模型命名空间里具有状态。特别的是,如果在不同的命名空间里存在着同一模型的二个版本,那么在每个命名空间里的Actor状态都能在Actor表里表示。

Actor_State表捕捉特定命名空间里的特定Actor的复合状态的活动子状态。这个表仅供内部使用,状态引擎用来来实现历史恢复。在actor和actor_state表之间存在着一对多的关系。

Actor_Property表保存特定命名空间里的特定Actor的用户自定义属性。每个属性都有一个名字(对于每个命名空间的每个Actor,名字必须是唯一的),一个类型,和一个值。这个表为客户应用程序提供了方便,可以把一组数据与角色关联;更常见的情况是,应用程序的数据保存在应用程序的数据存储机制里。

部署

StateMachine EJB会为每个状态模型部署一个不同的实例。每个实例的源代码是相同的(相同的home和 remote接口,相同的实现),但是具体的配置不同。StateMachine EJB的部署描述符指定了唯一的JNDI(Java命名和目录接口)名(客户用这个名字来定位EJB),还有一个对模型XML文件的引用。例如,保险状态模型的StateMachine EJB可能有一个 JNDI 名"state_insurance" ,并指向文件 "Insurance.xml"。要与这个模型交互,客户应用程序可以用"state-insurance"这个JNDI名来访问模型的EJB并调用EJB的方法。这个特殊的方法有着显著的优势:

·生命周期:要想准备好一个可供处理的新状态模型,需要部署一个指定该模型的StateMachineEJB。要想取消这个模型,需要取消EJB的部署。要把变化交给模型,需要用修改过的模型文件重新部署EJB。

·版本管理:如果现有的状态模型有一个新的主版本,那么新版本可以部署成独立的EJB,与以前的版本并存。

例如,“state-insurance-1.1”可以与“state-insurance”并存。

数据模型同样支持版本管理。给定的Actor有多个模型的持久状态,包括相同模型的不同版本,只有模型有不同的名称。.

大多数业务流程要运行相当长的时候,所以应用程序升级的管理变得极富挑战。有二个场景很难解决:

1.做了一个小补丁,但是有Actor正在用没有打补丁的版本运行着。

2. 做了一个主要补丁,只有新Actor可用,旧的Actor仍然使用以前的版。.

E-State 是解决这些问题聪明的解决方案:

1.应用小补丁,意味着为模型重新部署现有EJB。Actor会在停止的地方重新开始,补丁同时发挥作用。.

2.应用主要补丁,意味着用一个独立的命名空间部署新的EJB,而现在已经部署的EJB保持不变。模型彼此独立,这样老Actor用旧版本运行,新Actor用新版本运行。

结束语

E-State是由ROOM方法所启发的一个企业级状态机框架。它与BMP工作流集成在一起,提供了关键的集成服务,例如系统集成、事件、计时器、工作列表以及XML。这为开发面向流程的业务应用程序提供了强大的解决方案。E-State中包括:运行时引擎,状态模型架构,持久性服务,用户自定义“动作”类(在发生转换时,在进入或退出状态时,引擎会调用用户自定义“动作”类。)动作类调用工作流来利用BPM服务;而工作流被事件触发时,则调用引擎来触发转换。

参考资料 

·  Selic, Gullickson,and Ward. (1994). Real-Time Object-Oriented Modeling. Wiley.


你可能感兴趣的:(工作,workflow,weblogic,ejb,actor,引擎)