领域驱动设计方法的关键要素研究与应用_吴昌雨
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
比,为开展领域驱动设计提供借鉴.
关键词: 领域驱动设计; 领域模型; 六边形架构
中图分类号: TP311. 132. 1 文献标识码: A
DOI:10.16393/j.cnki.37-1436/z.2015.02.004
引言
传统的软件开发经常是分析与设计割裂的,一 个典型的例子就是在我国系统分析师、系统设计师 就是两种不同的职称,分析与设计分离导致的后果 就是分析的结果往往不能直接用于设计编程,设计 者需要从分析文档中给出数据设计逆推出系统的行 为,最终造成设计出的软件并不能真正的体现需求, 而领域驱动设计( Domain - Driven Design ,DDD) 是 Eric Evans 在 其 著 作 《Domain - Driven Design – Tackling Complexity in the Heart of Software》[1]中首
以教学资源共享平台开发为例,首先由领域专 家对其需求进行定义: 教师可以创建并管理课程; 课 程由章节构成,每个章节包括一定学时的教学内容; 章节中的教学内容由文档、视频、音频等教学资源构 成; 学生可以浏览并收藏课程内容.
如果是使用传统的面向对象程序设计方法,根 据其需求可以由动名词法得到一些实体类,类之间 包含一些属性及其 get / set 方法,这些实体类的作用 很单一,仅仅用于描述实体却没有任何与其业务逻 辑相关的 东 西,业 务 逻 辑 将 会 被 放 到 一 个 单 独 的 service 类中处理,这是一种典型的失血模型. 而采用 领域驱动设计方法则要求将业务逻辑集中于领域对 象中,同样是上面的例子,课程领域模型可以被视为 一个聚合,课程作为聚合根包含了章节与课程资源, 聚合根内部包含有状态,并且这种状态不能直接暴 露出去,另外聚合内部的对象通过聚合根实体与外 界交互. 因此从逻辑上得出这样一个结论: 教师、学 生作为用户与课程发生业务逻辑,而课程作为聚合 根其内部包含了章节及教学资源,即形成了图 2 所 示的领域模型.
String teacherID
看出每个模块通过一个定义好的接口被其他的模块
static constraints = {
访问,比如用户模块通过 IUserService 接口的实现类
name( blank: false)
UserService 服务与外部交互,其目的是降低系统耦
totalLesson( range: 1. . 1000)
Eric Evans 在《领域驱动设计》中给出了一个典 型的四层参考架构,分别是用于展示信息,并解释用 户命令的表现层; 起到协调、调度作用的应用层; 核 心的领域层,包括业务领域的信息,以及业务对象的 状态变更; 提供业务对象的持久化等支撑的基础设 施层.
这种分层架构很好的遵循了关注点分离的原 则,对领域对象进行了明确的策略和职责划分,让领 域对象和现实世界中的业务形成良好的映射关系, 相比于传统的软件架构分层有如下特点:
static hasMany = [lessons: Lesson]
程、Lesson———教学章节、Resource———教学资源. 这
String id
5 个领域对象按照功能划分为两个模块,分别是用
String name
户模块和课程模块,将这些高关联度的类划分到一
int totalLesson
个模块,可以提供尽可能大的内聚性,从图 3 中可以
2) 领域层不依赖于实现的细节,层与层之间松 耦合
在软件分层结构中,层通常是职责划分为独立 且紧密结合的单元,比如传统三层架构中 BLL 层负 责业务逻辑,它依赖于底层数据访问层的支持同时 也为其上级表示层提供依赖,这种层与层之间的依 赖关系看起来很自然,但在具体面对需求变化时,每 一个层次的变更都有可能影响到其他层,并对系统 的伸缩性产生负面影响. 而在 DDD 中,领域层虽然 负责处理整个系统的业务逻辑,但其设计是与其他 层松耦合,即与其上下层之间没有依赖关系,领域模 型业务逻辑的实现应该独立于持久化实现的细节.
15
2015 年
菏泽学院学报
第2 期
是不一致的,所以领域驱动设计的一个核心的原则 就是使用一种基于模型的通用语言( Ubiquitous Language) 实现相互的交流. 图 1 展示了通用语言是介 于开发者与领域专家组成的开发团队所使用的用于 统一其行动及帮助创建统一模型的语言.
图Leabharlann Baidu1 构建通用语言
事实上,DDD 的 具 体 实 现 并 不 依 赖 于 特 定 架 构,包括其参考架构的层次概念在实践中都是可以 忽略的,本文针对教学资源共享平台采用了图 3 所
2015 年
吴昌雨,等: 领域驱动设计方法的关键要素研究与应用
示的六边形架构( Hexagonal architecture) ,图中左边 是六边形架构,右边是资源共享平台实现过程中针
1 相关工作
领域驱动设计是面向对象的分析与设计 ( Object Oriented Analysis Design,OOAD) 的扩展和延伸,
用领域驱动设计后其架构演进的角度着手分析了如 何在既有项目上应用领域驱动设计并不断演进[3]; Jimmy Nilsson 在 其 著 作《Applying domain - driven design and patterns》( 领域驱动设计与模式实战) 中, 展示了如何应用测试驱动开发( TDD) 不断改进领 域驱动设计以及应用领域驱动设计创建高质量企业 级应用架构的过程[4].
合度. UserService 以及 CourseService 都属于 DDD 中
}
的领域服务,它为外部提供操作接口,负责对领域对
……
象进行调度与封装并提供各种形式的服务,服务执
}
行的操作代表了一个领域概念,被执行的操作通常
图 2 教学资源共享平台领域模型
16
这种领域模型准确的反应了业务,业务逻辑不 是放在单独的业务逻辑类中处理,而是包含在领域 对象中,每个领域对象都是包含了属性与业务逻辑 相对完整的独立体,并与现实领域中的业务对象一 一映射. 领域模型则是由这些领域对象组成. 这种设 计方法,即 保 证 了 系 统 的 可 维 护 性、扩 展 性 和 复 用 性,同时也在处理复杂业务逻辑方面具有先天优势. 2. 2 架构设计
1) 应用层不包含业务逻辑,由领域层处理具体 的业务操作
传统三层架构软件设计中,有专门用于处理业 务逻辑的业务逻辑层( BLL) ,在这样的架构中,随着 需求的变更业务逻辑处理类开始积聚越来越多的业 务逻辑,而领域对象则成为单纯的数据载体造成了 “肥的服务层”和“贫血的领域模型”. 而在 DDD 方 法指导下,领域模型应该侧重于具体的业务操作领 域. 领域对象由实体和值对象构成,实体类具备自己 的属性和行为、状态,可以聚合,实体类之间可以有 聚合关联等关系,可以借由基础设施层进行持久化.
基于领域模型,教学资源共享平台的通过设计 与分析教学资源共享平台领域层设计图如图 4 所 示:
17
2015 年
菏泽学院学报
第2 期
图 4 教学资源共享平台领域建模
图 中 领 域 对 象 和 现 实 业 务 的 对 应 关 系 为:
class Course {
Teacher———教 师、Student———学 生、Course———课
2 领域驱动建模及架构设计
2. 1 构建领域模型 和传统软件开发一样,软件开发首先是从软件
专家与项目领域专家的交流开始,但这种交流通常 会存在障碍,原因是双方思维方式及问题的侧重点
* 收稿日期: 2015 - 01 - 14 基金项目: 安徽省省级特色专业( 2013tszy063) ; 安徽省高等学校省级教学研究项目( 2013jyxm360) ; 滁州职业技术学院 院级教学研究项目( zlgc2013025) 作者简介: 吴昌雨( 1977 - ) ,男,安徽滁州人,讲师,工学硕士,研究方向: 计算机应用技术软件技术.
次提出的一种用于指导复杂软件设计与开发的一整 套基于领域模型的系统分析和设计的方法. 它将软 件分析与设计的关注点从数据引导到业务上来,打 破了分析与设计的隔阂,提出了领域模型概念,使得 软件能够适应更灵活的需求变更.
本文从教学资源共享平台的分析与设计入手, 阐述了领域驱动设计的相关理论及其应用,通过应 用六边形架构实现了系统原型,为类似软件开发过 程中领域驱动设计方法的应用提供借鉴.
第 37 卷第 2 期 Vol. 37 No. 2
菏泽学院学报 Journal of Heze University
2015 年 4 月 Apr. 2015
文章编号: 1673 - 2103( 2015) 02 - 0015 - 05
领域驱动设计方法的关键要素研究与应用*
吴昌雨,王善勤,李云松,刘青,邹军国
对六边形架构的一些具体实现.
第2 期
图 3 六边形架构
这种六边形架构也可以称之为端口和适配器架 构( Ports and Adapters architecture) [5],该架构设计 目标是实现层次之间的解耦,在其核心的领域模型 中包含了所有的业务逻辑与规则 ( 但并不直接实 现,由基础设施层通过 DI 注入) ; 包围领域模型的 是应用程序端口层,它负责接收请求,并交由领域层 处理,这一层很薄,主要起到协调作用; 最外层的是 适配器层,负责以某种格式接受输入并产生输出,比 如通过 HTTP 接受客户端请求并封装为端口能够理 解的方式交给端口,再将处理结果转换为 HTTP 相 应反馈给客户端. 该架构的特点是组件与组件之间 是相互平等的,模糊了层次概念,因为各层次之间的 交互并不依赖于各自于实现的细节,都是通过接口 实现,这一特性的实现取决与软件抽象及一些新技 术手段的运用. 具体来说,该架构的实现需要以下三 种技术手段的配合:
3. 1 领域层设计实现 领域对象由实体及值对象构成,实体( Entities)
类具有唯一的 ID,能够实现持久化等业务逻辑,对 应 于 现 实 世 界 中 的 业 务 对 象,在 系 统 中 设 计 了 Course 等实体类; 值对象无 ID,由对象属性描述,可 用于传递数据或对实体进行补充描述.
3) AOP( Aspect Oriented Programming,面向方面 编程) ,AOP 可以很好的实现关注点横切,比如可以 使用 AOP 将领域对象的业务规则检查、状态变化跟 踪、数据缓存、事务管理等某个方面的问题从领域对 象中移除出来,让领域对象更好的关注业务.
3 教学资源共享平台设计实现
( 滁州职业技术学院,安徽滁州 239000)
摘要: 针对传统软件设计中分析与设计割裂等问题,研究了领域驱动设计的相关理论、要素及特点,阐述
了如何构建领域模型,并在其分层结构的基础上提出了基于六边形架构实现领域驱动设计的思路与方法,以
高校教学资源共享平台设计与实现为载体,对领域驱动设计中一些关键要素的设计与实现进行了分析和对
它既是面向对象设计的补充,又完成了对面向对象 设计的超越,相对 OOAD 而言,它的主要变化在于 能够使用领域模型准确反应业务语言,也正因为此, 它几乎成了目前开发大中型复杂软件系统的主流方 法. 国内外研究学者对领域驱动设计的核心构成要 素如分层架构、实体、值对象服务等概念展开了大量 研究. 例如 Vaughn Vernon 的《Implementing Domain - Driven Design》( 实现领域驱动设计) 从战略设计 高度研究了包括领域、实体、值对象、受限上下文等 概念如何设计,并从战术设计的角度研究了其如何 实施[2]; Mat Wall 等人从 Guardian. co. uk 网站,采
1) OOP( Object Oriented Programming,面向对象 编程) ,OOP 仍然是领域实现中的重要原则,应充分 利用其封装、继承、接口等特性设计领域对象;
2) DI( ( Dependency Injection,依赖注入) ,DDD
要求领域对象既要具有业务逻辑但又不能依赖于具 体实现细节,则只能通过 DI 的方式将数据持久化等 业务逻辑注入到领域对象中;