传统编程模型可以采用最经典的状态模式构建状态机,已达到刻画对象生命周期的目的。在这种编程模型中,为了表达一个状态转移需要应用程序员编写下面类似的代码。
例如在Android开放源代码中的StateMachine.java
Java代码
private class HaltingState extends State { 728 @Override 729 public boolean processMessage(Message msg) { 730 mSm.haltedProcessMessage(msg); 731 return true; 732 } 733 } ... private class QuittingState extends State { 739 @Override 740 public boolean processMessage(Message msg) { 741 return NOT_HANDLED; 742 } 743 }
这种虽然完全可以表达状态机的语义并且对于生命周期的变化也非常容易扩展。但是存在以下几个缺点:
- 要想观看状态机的全貌,这种表达不是很直观。
- 状态机描述与业务代码的耦合,导致状态机不能重用,这也是把这个状态作为内置类的一个原因。比如若QuittingState根据不同的Message可以去到不同的State,那么业务代码的逻辑判断必须融合到这个QuitingState当中。这个生命周期部分的描述就不可以给其他对象重用。表达方式抽象程度不够。
- 没有改变开发实践,未能在开发实践中突出对象生命周期设计的重要性。倘若将生命周期通过元数据的方式描述同时与业务代码分开,那么在开发实践中,生命周期的设计工作可以跟团队中设计能力较强的同事的来进行,而经验不丰富的同事可以来编写一般意义上的计算逻辑或者业务逻辑。若有生命周期上的调整,直接修改的是元数据的部分,而不是业务代码的部分,当然如果计算逻辑需要调整一定要修改业务代码。这样的好处是可以让生命周期元数据部分受到更好的管控。而不是在某一个业务对象的Java文件里的某一行修改。
- 生命周期回调以及状态变化事件的监听,依然需要采取类似于Observer的方式进行。这也是微妙的控制结构表达的问题。这种编程模型是过去比较流行的,现如今Annotation大行其道,通常为了实现回调功能,过去需要写一个类实现一个接口,而现如今只需要声明一个方法,并添加一个Annotation即可,虽然思想相同,但是表达方式更加的简洁。
Lifecycle的原型在5年前逐渐的演化,从仅仅通过Hash算法进行Transition(转移)的合法性校验,到使用状态模式在processMessage方法中编写更多的业务逻辑。到使用Java Reflection + 动态代理 来进一步简化编程模型,使用元数据描述生命周期,使得生命周期与业务代码分离。再到现如今的通过 Java Instrument在运行时 或者 编译时修改class字节码,以便去掉Java 动态代理必须要求一个接口的多余限制。旨在使得编程模型变得更加简洁。这个路线也是大多数开源软件框架的路线。比如EJB框架,从EJB2.0 必须实现 Home接口和EJB接口,到只需要@Stateless类似的注释即可完成与容器之间的交互。
不过生命周期框架的核心思想是:对于OO设计和编程,要重视生命周期的设计,以减少多年后软件或者软件服务升级所带来的苦恼,包括减少代码量,减少测试代码。从对象与对象的交互出发,通过生命周期这把标尺来设计一个概念的范围,比如一个类的范围,哪些行为哪些属性应该包含在一个概念当中,对象与对象之间的关系也是通过生命周期这把标尺来衡量。
至于表达方式,满足产品本身的性质即可。如果是一个很小的软件,也没有很长的维护周期,那么一个状态模式就已经足够好了。对于复杂的软件,包含很多业务对象,甚至有较深的层级关系,对象与对象之间的关系比较复杂,这个时候采用元数据来描述各自的生命周期以及约束,把生命周期相关的工作交给生命周期引擎完成,就是更好的选择。
Lifecycle 基于有限状态机的数学模型定义了编程模型。Lifecycle的编程模型有两部分构成:
- 生命周期的元数据描述
- POJO
生命周期元数据包括以下几部分:
- 状态集合 @StateSet,定义了初始状态@Initial,最终状态@End,其他状态,
- 转移集合 @TransitionSet, 定义了生命周期中全部转移
- 关系集合 @RelationSet,定义了生命周期关系型约束中需要的全部关系
- 条件集合 @ConditionSet,定义了条件转移中的全部条件接口
其中生命周期元数据描述部分与POJO部分分离,这使得在一些复杂情况下,生命周期元数据自身的多态性可以增加重用能力。而POJO部分并不需要编写额外的代码。只是需要通过Annotation指明Lifecycle Engine需要的状态指示器、转移方法、条件转移、关系对象Getter、生命周期回调方法。
@StateMachine protected static interface CustomerLifecycleMeta { @StateSet static interface States { @Initial @Function(transition = CustomerLifecycleMeta.Transitions.Activate.class, value = { Active.class }) static interface Draft {} @Functions({ @Function(transition = CustomerLifecycleMeta.Transitions.Suspend.class, value = Suspended.class), @Function(transition = CustomerLifecycleMeta.Transitions.Cancel.class, value = Canceled.class) }) static interface Active {} @Function(transition = CustomerLifecycleMeta.Transitions.Resume.class, value = Active.class) static interface Suspended {} @End static interface Canceled {} } @TransitionSet static interface Transitions { static interface Activate {} static interface Suspend {} static interface Resume {} static interface Cancel {} } }
如上述代码片段中,描述了一个简单业务对象的生命周期元数据,它仅包括了状态集合States以及转移集合Transitions。其中状态集合中包含了Draft, Active, Suspended, Canceled四个状态,其中Draft是初始状态(通过@Initial标注),Canceled是最终状态或终结状态(通过@End标注)。转移集合中包含了Activate, Suspend, Resume以及Cancel四个转移。状态与转移之间的关系通过@Function刻画,如下段代码中的@Function用来描述,当对象处于Draft状态上,转移Activate可以将对象变换到Active状态;而其他转移对于Draft状态是无效的。
@Initial @Function(transition = CustomerLifecycleMeta.Transitions.Activate.class, value = { Active.class }) static interface Draft {}
POJO部分代码如下:
对于这个简单POJO,即使没有生命周期框架的支持,上面代码片段中的四个业务方法以及对状态属性赋予初始值还是要写的,除此以外还要定义状态模式的四个状态类,然后以紧耦合的方式将状态模式的processMessage方法与四个业务方法联系到一起。而有了生命周期框架的支持,在定义了状态属性以及四个业务方法以后,仅需要对其进行标注。其中@StateIndicator用来指明LifecycleEngine从哪里读取当前业务对象的状态或向哪里写入新的状态。@Transition用来表明某个方法是一个转移方法,可以通过@Transition(Cancel.class)来对应生命周期元数据中的Cancel转移,也可以通过方法名称cancel首字母大写后与Cancel类的SimpleName相匹配。
- @StateIndicator
- private String state = null;
- @Transition
- public void cancel() {}
在实际的设计与编程实践中,可以由偏向设计职能的同事完成生命周期的设计并产生生命周期描述元数据,由偏向业务逻辑编写职能的同事完成业务代码的编写。这使得生命周期设计本身与源代码的生命周期始终保持一致,因为元数据本身就是代表了生命周期的设计。任何情况下对业务对象生命周期的调整都必须修改生命周期元数据描述,这也使得只要通过生命周期元数据描述,就可以确切的知道当前业务对象的生命周期的设计。而相对于经典的状态机设计模式,生命周期元数据描述更具表达能力,更简洁清晰。省去了必须在processMessage方法控制结构中返回下一个状态的表达约束。
除此以外,生命周期引擎还提供状态校验,转移校验,关系约束校验,条件转移,新状态设置,生命周期回调,生命周期事件传播,可插拔的并发锁控制等功能。
更多示例代码:
相关推荐
标题中的“生命周期组件框架——关系型状态机服务”暗示了我们即将探讨的是一个与软件开发相关的框架,特别关注的是对象或组件在其存在期间的行为管理。生命周期管理是编程中一个重要的概念,它涉及到对象从创建、...
ASP.NET WebSite编程模型具有以下特点: q 动态编译该页面,而不用编译整个站点。 q 当一部分页面出现错误不会影响到其他的页面或功能。 q 不需要项目文件,可以把一个目录当作一个Web应用来处理。 总体来说,ASP...
MVC模式强调分离关注点,而Web Forms则基于传统的桌面编程模型,提供事件驱动的开发体验。 6. **ASP.NET Core**:作为ASP.NET的最新版本,ASP.NET Core是一个跨平台的高性能框架,支持.NET Core和.NET Framework。...
软件生命周期模型是软件开发过程中的一种框架,它定义了从软件项目的启动到最终退役的各个阶段及其顺序,为软件工程提供了一种结构化的方法。本篇文章将深入探讨软件生命周期模型,包括其重要性、常见模型以及在实际...
ASP.NET 编程模型是微软开发的Web应用程序框架的核心组成部分,它定义了处理客户端请求的整个生命周期。在ASP.NET中,编程模型主要包括HttpApplication、HttpModule、HttpHandler和相关事件的执行顺序。以下是对这些...
(a)软件生命周期模型是软件开发过程中的一种重要框架,它描述了软件从概念形成到最终退役的各个阶段。软件生命周期模型通常包括多个阶段,每个阶段都有其特定的目标和任务,为软件项目的成功实施提供了结构化的路径...
该平台致力于建设数据清洗、特征处理、模型训练、模型生命周期管理、在线预测等功能。 编程模型演进 - MapReduce编程模型: MapReduce编程模型是阿里云机器学习平台的核心组件之一,该模型解决了分布式难题,计算...
9. **生命周期方法**:在某些编程语言和框架中,领域对象可能包含一些生命周期方法,如 `save()`、`delete()`、`load()` 等,用于操作对象的生命周期。 10. **CQRS(命令查询责任分离)**:在复杂系统中,CQRS 模式...
综上所述,软件安全开发生命周期是一个全面的框架,涵盖了从需求分析到部署的各个阶段,旨在通过早期介入安全策略来降低软件安全风险。遵循SDL,开发者能够创建出更为健壮和安全的软件产品,保护用户的数据和企业的...
每个角色都有其特定的职责和工具链,以确保从需求分析到部署监控的整个生命周期中,能够高效协同工作。 例如,业务分析师使用Rational Requisite Pro进行需求收集和模拟分析,帮助定义清晰的业务模型。开发者使用...
6. **服务治理**: 管理服务生命周期,包括变更、升级、退役等。 7. **服务监控与优化**: 监控服务性能,持续改进服务质量和响应时间。 IBM SOA编程模型强调的是灵活性和可扩展性,通过模块化和松耦合的设计,使得...
Promise框架主要作用在于简化异步编程模型,使其更加易于理解和使用。异步编程与同步编程的主要区别在于函数调用时,控制权的转移和消息的传递方式。在同步模式中,被调用函数( callee)需要执行完成并将结果返回后...
Windows Vista的受管代码编程模型,也被称为WinFX,是一个重要的软件开发框架,它整合了Win32 API和.NET Framework的进化,旨在提供更高效、更安全的开发环境。WinFX的目标是帮助开发者应对现代软件开发中的挑战,...
9. **组件生命周期管理**:包括对象的创建、初始化、使用和销毁,.NET框架提供了一些内置的生命周期管理机制,如Singleton模式、 Dispose模式等。 10. **元数据**:.NET组件通过元数据来描述自身,这使得反射成为...
在本次讲座中,我们将给大家详细介绍有关ASP.NET页面框架的一些知识,如页面生命周期、页面事件、页面指令、页面编程模型等等。 <br/> 课程讲师: 邵志东 MSDN特邀讲师 北京新科海学校 副总经理 <br...
VB6提供了一种直观的事件驱动编程模型,通过事件处理函数响应用户的操作。同时,测试也是这一阶段的重要环节,包括单元测试、集成测试和系统测试,以确保软件的质量和稳定性。 4. 维护与更新:软件发布后,会根据...
ASP.NET页面框架是微软开发的一款用于构建动态web应用程序的强大工具,尤其在Visual Studio 2003的时代,它为开发者提供了高效、灵活的编程模型。本文将深入探讨ASP.NET页面框架在VS2003环境中的核心概念和关键特性...
4. **Composite**: 通过`RACDisposable`,你可以管理信号订阅的生命周期,防止内存泄漏。同时,`RACGroupedLock`等工具可以帮助你处理多线程问题。 **在Swift开发中的应用** 尽管`ReactiveObjC`主要是面向...
51编程C#敏捷开发框架可能内置了DI容器,允许开发者通过接口而不是具体实现来管理对象的生命周期。 2. **MVC(Model-View-Controller)**:模型-视图-控制器架构模式是Web应用开发中的常用模式,它将业务逻辑、数据...
尽管Spring框架自身对编程模型没有限制,但其在Java应用中的频繁使用让它备受青睐,以至于后来让它作为EJB(EnterpriseJavaBeans)模型的补充,甚至是替补。Spring框架为开发提供了一系列的解决方案,比如利用控制...