Page 33 - 《软件学报》2021年第9期
P. 33
贾子甲 等:领域驱动设计模式的收益与挑战:系统综述 2657
够从不同视图进行领域建模,而其中每个视图都代表了特定涉众的观点.
3.4.3 领域模型实现
在领域模型实现部分,本文发现了 5 种应用 DDDP 的挑战(即 C10~C14),并且对于其中的 C12 和 C13 寻找
到了对应的缓解方法(M13,M14).
• 挑战
本研究发现:在领域模型的实现过程中,防腐层(anticorruption layer)与服务(service)的实现复杂度较高(对
应 C10 与 C11).对前者而言,文献[41]提到,实现防腐层的最大挑战在于控制转换复杂度,也就是开发人员必须充
分理解两个限界上下文及其关联;而对后者而言,文献[43]指出,应确定服务的粒度来确保能够提供合理的对相
关领域的访问.由于 DDD 主要关注领域模型,并没有对服务实现给出详细指导,因此为实现过程造成了一定的
困难.
此外,由于 DDD 侧重于业务领域而非技术领域,这也带来了两项挑战.
• 第一,DDD 中的领域模型没有指定后续的实现规范(C12).举例而言,领域对象的属性可能是无类型的,
或者缺少具体的行为方法 [48] .但是这类信息对于后续实现而言往往是必要的,而由于这类信息的缺失,
使得从模型清晰地推断出技术特性变得非常困难;
• 第二,领域模型并不包含基础组件或部署视图中的基础设施(C13),但这类视图或组件信息有时会在很
大程度上影响软件系统,特别是在微服务场景中.因此,这类信息需要使用文档加以记录来作为对模型
的补充.
模型驱动开发(model-driven development)能够提高领域模型到代码转化的效率,在 DDD 中得到了较广泛
的应用.然而,即使在将领域模型正确转换为代码之后,由于领域建模过程的不断迭代,仍然有可能需要重复这
一过程.因此,模型到代码转换的自动化(C14)十分必要.而为了使得模型与代码始终保持一致,则需要在建模的
[1]
每个迭代过程中持续地关注各个领域元素 .尽管在 DDD 中引入了模型驱动设计,但如何在模型的细化过程中
保证代码和模型的一致性 [44] ,仍然是一个难题.
• 缓解方法
建模规约(convention) [48] 意味着为建模过程设置需要遵守的规则.建模规约通过为领域模型赋予更多形式
化内容,来应对 DDD 中领域模型缺乏实现规范的挑战(C12).文献[48]中提供了一些规则示例,比如在建模时禁
止双向关联、事先规定引入微服务接口的 DDDP 等.针对领域模型中缺少基础组件的情况(C13),文献[48]建议
利用来自模型驱动开发 [63] 的中间模型来表示技术特性,如接口模型和部署模型等.前者用于对服务接口进行建
模,后者用于对可部署工件进行建模.这些中间模型能够展示特定角度的技术特性,有助于接口类型和部署技术
的进一步实现.
3.4.4 普适性活动
在普适性活动部分,本文发现了 3 种应用 DDDP 的挑战(即 C15~C17),并且对于其中的每个挑战寻找到了对
应的缓解方法(M15~M17).
• 挑战
文献[37]提到:在形成通用语言的过程中,由于不同涉众使用的语言不同,往往难以对于同一术语形成统一
认识(C15).这使得团队在沟通过程中可能会产生误解,想要定义通用语言往往需要付出更多的努力.
[4]
领域模型的获取与变更管理,是应用 DDDP 的另一项挑战.Vernon 建议由单个团队来开发和维护一个限
界上下文及其对应的模型.但是,管理不同团队对领域模型的权限也会遇到挑战(C16),因此必须确定团队对领
域模型的权限范围.此外,是否允许团队更改其他团队的领域模型也很重要.以上决策将直接影响到模型的变更
情况 [38] .比如:如果允许团队更改其他团队的限界上下文,服务之间的依赖会变得更加复杂.因此,应该权衡每个
决策所带来的损失和收益,从而做出最终决策.
最后,C17 与应用 DDDP 进行软件开发的过程相关.领域驱动设计的核心原则是,使应用程序与领域模型保
[1]
持一致.正是这一特点,使得领域驱动设计区别于其他传统的软件开发方法 .然而,虽然这一方法目前已经被广