基于领域消息驱动的轻量级Spring—DDD插件设计与实现
作者:王薇 黄强
来源:《现代电子技术》2015年第24期
作者:王薇 黄强
来源:《现代电子技术》2015年第24期
摘 要: 领域驱动开发(DDD)是完全基于内存的业务对象建模(In⁃Memory)方法,而目前的DDD框架不能完全覆盖系统业务,也不成熟稳定,无法应用于实际项目的开发。在Spring框架的基础上,实现了一个基于领域消息驱动和内存建模的DDD插件,在不影响目前系统架构的基础上,让项目实施完全兼容DDD设计。同时基于JDK和Disruptor并发框架实现的领域事件消息和领域对象缓存模型,有效地降低了系统的解耦关系,并提高了系统的整体性能及效率。
关键词: 领域消息驱动; 内存建模; 领域事件; 领域缓存
中图分类号: TN911⁃34; TP319 文献标识码: A 文章编号: 1004⁃373X(2015)24⁃0062⁃04
Design and implementation of light⁃weighted Spring⁃DDD plug⁃in driven by
domain message
WANG Wei1, HUANG Qiang2, 3
(1. Department of Electronic Business, Sichuan Finance and Economics Vocational College, Chengdu 610101, China;
2. College of transportation, Southwest Jiaotong University, Chengdu 610031, China;
3. College of Information and Engineering, Sichuan Agricultural University, Ya’an 625014, China)
Abstract: DDD (domain driven development) is entirely memory⁃based business object modeling (In⁃Memory) method, but the current DDD framework is not stable enough to cover the system business completely and can not be applied to the development of practical project. On the basis of Spring framework, the DDD plug⁃in based on domain message driving and memory modeling was realized, in which the impl
ementation of the project is fully compatible with DDD design without affecting the current system architecture. The domain event message and domain object caching model based on JDK and Disruptor concurrency control framework can effectively reduce the decoupling relationship and improve the whole performance and efficiency of the system.
Keywords: domain message⁃driven; memory modeling; domain event; domain cache
0 引 言
领域建模(Domain Modeling,DM)的初期是基于对象关系映射的ORM(Object Relationship Mapping)技术。ORM通过数据库与对象的数据映射,初步解决了关系与对象的不匹配问题[1],使系统设计分析人员能够采用纯粹的对象技术来解决领域问题。但是随着业务分析的深入,ORM产生的贫血对象模型由于行为能力的缺失,让系统又从对象模型退化为事务处理过程,与DM理论逐渐背离;随后为了避免贫血模型的弊端而出现的充血模型,将业务与数据全部合并到领域模型中。在后来的几年中,有很多框架都在充血模型的理论基础上进行了大量实践(如ROR,Grails,Spring Roo等),这些快速开发框架出现的初期在
小型项目上应用非常成功。但是随着业务增长,领域对象会急速膨胀,维护难度会急剧增加,让系统处于一个不可控的状态,并且业务和数据的领域整合会让系统的结构变得模糊不清,给系统带来另外的压力,所以这类框架始终没有能成功地应用到大型项目开发中去。在2004年,著名的软件工程专家Evans提出了一个全新的领域开发模型Evans DDD[2]。Evans DDD不但弥补了ORM的对象行为缺失和生命周期问题,也通过领域聚合和分解有效地解决了充血模型随着领域扩大而迅速臃肿的缺陷,为大型系统设计和开发提供了一个合理的解决途径。但是由于Evans DDD的设计理念比较灵活,依附于业务设计,且始终没有一个统一的底层技术构架来支持该模型,导致系统开发人员很难将系统分析转换为编码,故大大降低了系统的实施效率。同时现有的框架体系基本是以数据库为核心的分层结构,也为DDD的实践造成了很大的障碍。一些全新的框架由于不能很好地兼容以前的遗留系统,也很难得到推广。为此,本文以Java为例,在充分利用目前广泛使用的Spring开发框架基础上,提出了一种基于AOP和JDK Concurrent/Disruptor并发框架实现的领域事件消息和领域对象缓存模型,并完成了能够较好兼容Evans DDD的整套领域驱动开发插件Takia。在多个项目中的实施证明,该插件在保证系统开发效率的前提下,能够有效匹配基于DDD的设计方案,消息模型使领域对象之间以及领域对象与服务仓储等组件之间的交互变得更加灵活。配合领域缓存,
可以完全消除领域对象对数据库的依赖,能够很好地为系统构架师所利用,以权衡系统整体的得失做出全局性的决策,让系统的综合性能达到最高,为基于DDD的项目分析和实施提供有效的架构指导。
1 基于消息的轻量级Spring⁃DDD领域插件模型
Takia构架设计
本文提出的异步领域消息模型能够更好地适应领域对象的作用关系和领域扩张问题,更好地支持领域建模。Takia以领域的四要素为基础[3],采用分布式缓存系统实现了领域的In⁃Memory模型,并提出基于异步消息的数据通信方式,优化了领域对象的生产和存储性能,很大程度提高领域对象之间的解耦程度,以及领域对象的高并发数据处理能力,其整体构架如图1所示[ 4⁃6]。
从图1中可以看出,该构架底层基于Spring业务框架,Hibernate ORM框架和数据库管理系统,对于常规模型的开发人员来说相对比较熟悉,能够较容易地完成开发过渡,而Takia插件构架于Spring业务框架之上用以提供领域建模支持。在系统设计时,业务模块在被划分
成多个领域进行分散式并行开发,一个领域一般由领域对象(Domain Object)、值对象(Value Object)、服务(Usecase Service)和仓储(Repository)等组件构成[7];领域的外围是Takia提供的透明缓存和消息服务,这些服务通过基于Annotation的领域模型配置,使用AOP方式注入到相关的领域对象中,缓存用于提升领域对象的性能,消息用于降低系统及模块之间的直接耦合。Takia在设计时支持多种缓存实现,默认为EhCache以支持集和云结构。
图1 Takia DDD的总体构架模型
2 Takia的消息模型设计
并发的事件驱动模式是Takia的重要特点。通过DomainMessage作为桥梁来实现领域组件之间的信息交互,同时采用AOP编程模型,取代了传统的面向对象设计(OOSD)中,组件的直接组合和继承耦合,有效地消除了服务和仓储组件对领域模型的结构污染。Takia采用标准的生产者⁃消费者(Producer⁃Consumer)设计模式构架领域消息模型,并针对虚拟机内
部机制进行有效的优化,除了支持普通的JDK一对一同步/异步消息以外,还提供了高并发环境下的基于Disruptor框架的一对多异步消息支持,有效地解决了传统JavaEE分层构架的高并发环境下系统吞吐量迅速衰减的问题。下面依次对JDK和Disruptor两种消息模型结构进行分析。
2.1 JDK⁃Future消息模型设计
Future消息模型基于JDK的Concurrent包实现,核心组件是ChannelExecutor。该组件由一个线程池(ThreadPool)和一个同步组件组成,用于运行消息(MessageListener)。当使用异步模式时,由ThreadPool来运行MessageListener;使用同步模式时,由同步组件将MessageListener放入当前线程中执行。Future消息模型的详细结构和处理过程如图2所示。
由图2可以看出,DomainMessage作为消息生产者DomainObject和消息消费者MessageListener之间的桥梁用以传递信息,由事件源(EventSource)和Future结果事件(FutureResultEvent)组成,结果事件中包含了结果对象,事件元数据配置和一个FutureTask对象,FutureTask作为简单的内存障(MemoryBarrier),与ChannelExecutor配
合使用用以保证消息的一致性。由于受到Future机制的限制,在Future模式下只支持1∶1的生产者和消费者通信模式。
图2 Future消息模型的详细结构和处理过程
消息过程由DomainObject发起,通过调用DomainEvents(消息总线)创建一个DomainMessage对象后,DomainObject将事件源(EventSource)传递给DomainMessage(事件源即DomainObject传递给MessageListener的信息);接着DomainEventsspring framework组件会通知消息(MessageInterceptor)对DomainMessage的ResultEvent进行初始化,完成消息创建过程;然后MessageInterceptor调用EventMessageFirer发送消息,EventMessageFirer将Future消息的发送委托给FutureFirer,其根据消息配置从IoC容器中获取MessageListener组件后和DomainMessage一起放入ChannelExecutor执行。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论