张逸解构DDD:软件的核心是为用户解决领域相关的问题(3)

简介: 张逸解构DDD:软件的核心是为用户解决领域相关的问题(3)

子领域的边界明确了问题空间中领域的优先级,限界上下文的边界则确保了领域建模的最大自由度。这也是战略设计在分治上起到的效用。当我们在战略层次从问题空间映射到解空间时,子领域也将映射到限界上下文,即可根据子领域的类型为限界上下文选择不同的建模方式。例如为处于核心子领域的限界上下文选择领域模型(domainmodel)模式,为处于支撑子领域(supporting subdomain)的限界上下文选择事务脚本(transactionscript)模式,这样就可以灵活地平衡开发成本与开发质量。


战术设计阶段需要在限界上下文内部开展领域建模,前提是你为限界上下文选择了领域模型模式。在限界上下文内部,需要通过分层架构将领域独立出来,在排除技术实现的干扰下,通过与领域专家的协作在统一语言的指导下逐步获得领域模型。战术设计阶段最重要的设计元模型是聚合模式。虽然聚合是实体和值对象的概念边界,然而在获得了清晰表达领域知识的领域模型后,我们可以将聚合视为表达领域逻辑的最小设计单元。果领域行为是无状态的,或者需要多个聚合的协作,又或者需要访问外部资源,则应该将它分配给领域服务。


至于领域事件,则主要用于表达领域对象状态的迁移,也可以通过事件来实现聚合乃至界上下文之间的状态通知。战略设计与战术设计并非割裂的两个阶段,而是模型驱动设计过程在不同阶段展现出来的不同视图。战略设计指导着战术设计,这就等同于设计原则指导着设计决策。EricEvans就明确指出,“战略设计原则必须把模型的重点放在捕获系统的概念核心,也就是系统的‘远景’上。”当一个业务系统的规模变得越来越庞大时,战略设计高屋建瓴地通过限界上下文规划了整个系统的架构。只要维护好限界上下文的边界,管理好限界上下文之间的协作关系,限制在该边界内开展的战术设计所要面对的就是一个复杂度得到大幅降低的小型业务系统。人们常以“只见树木,不见森林”来形容一个人不具备高瞻远瞩的战略眼光,然而,若是“只见森林,不见树木”,也未见得是一个褒扬的好词语,它往往可以形容一个人好高骛远,不愿意脚踏实地将战略方案彻底落地。


无论战略的规划多么完美,到了战术设计的实际执行阶段,团队在开展对领域的深层次理解时,总会发现之前被遗漏的领域概念,并经过不断的沟通与协作,“碰撞”出对领域的新的理解。对领域概念的新发现与完善除了能帮助我们将领域模型突破到深层模型,还可能促进我们提出对战略设计的修改与调整,其中就包括对限界上下文边界的调整,从而使战略设计与战术设计保持统一。从战略设计到战术设计是一个自顶向下的设计过程,体现为设计原则对设计决策的指导;将战术设计方案反馈给战略设计,则是自底向上的演化过程,体现为对领域概念的重构引起对战略架构的重构。二者形成不断演化、螺旋上升的设计循环。


领域模型驱动设计


领域驱动设计是一种思维方式[8]2,而模型驱动设计则是领域驱动设计的一种设计元模型。因此,模型驱动设计必须在领域驱动设计思维方式的指导下进行,那就是面向领域的模型驱动设计,或者更加准确地将其描述为领域模型驱动设计。领域模型驱动设计通过单一的领域模型同时满足分析建模、设计建模和实现建模的需要,从而将分析、设计和编码实现糅合在一个整体阶段中,避免彼此的分离造成知识传递带来的知识流失和偏差。它树立了一种关键意识,就是开发团队在针对领域逻辑进行分析、设计和编码实现时,都在进行领域建模,产生的输出无论是文档、设计图还是代码,都是组成领域模型的一部分。EricEvans将那些参与模型驱动设计过程并进行领域建模的人员称为“亲身实践的建模者”(hands-on modeler)。



模型驱动设计主要在战术阶段进行,换言之,整个领域建模的工作是在限界上下文的边界约束下进行的,统一语言的知识语境会对领域模型产生影响,至少,建模人员不用考虑在整个系统范围下领域概念是否存在冲突,是否带来歧义。由于限界上下文拥有自己的内部架构,一旦领域模型牵涉到跨限界上下文之间的协作,就需要遵循限界上下文与上下文映射的架构约束了。


既然模型驱动设计是面向领域的,就必须明确以下两个关键原则。


  • 以领域为建模驱动力:在建模过程中,针对领域知识提炼抽象的领域模型,并不断针对领域模型进行深化与突破,直到最终以代码来表达领域模型。


  • 排除技术因素的干扰:领域建模与技术实现的关注点分离有助于保证领域模型的纯粹性,也能避免混淆领域概念和其他只与技术相关的概念。



模型驱动设计不能一蹴而就。毕竟,即使通过限界上下文降低了业务复杂度,对领域知识的理解是一个渐进的过程。在这个过程中,开发团队需要和领域专家紧密协作,共同研究领域知识。


在获得领域模型之后,也要及时验证,确认领域模型有没有真实表达领域知识。一旦发现遗漏或失真的现象,就需要重构领域模型。首先建立领域模型,然后重构领域模型,进而精炼领域模型,保领域概念被直观而真实地表达为简单清晰的领域模型。显然,在战术设计阶段,模型驱动设计也应该是一个演进的不断完善的螺旋上升的循环过程。



本文摘录于张逸老师新书《解构领域驱动设计》。


相关文章
MapStruct - 生成空对象解决方案
MapStruct - 生成空对象解决方案
1977 0
|
存储 前端开发 测试技术
DDD - 六边形架构和CQRS架构
DDD - 六边形架构和CQRS架构
1803 0
|
前端开发 测试技术 API
DDD领域驱动设计实战-分层架构及代码目录结构(上)
DDD领域驱动设计实战-分层架构及代码目录结构
2128 0
DDD领域驱动设计实战-分层架构及代码目录结构(上)
|
2月前
|
人工智能 安全 API
OpenClaw养虾保命指南:6大必装安全Skill+全平台部署+阿里云百炼安全配置实战手册
2026年OpenClaw(龙虾)全面普及,但ClawHub上已出现**超1000个恶意Skill**,专门窃取SSH密钥、浏览器密码、加密钱包、API Key,一旦乱装插件,系统随时可能被接管、数据被窃取。对于新手而言,**装Skill不是越多越好,而是先装“保命、防坑、安全、稳定”的核心插件**。
760 1
|
IDE Linux 开发工具
Linux系统、版本、CPU、内存查看、硬盘空间
*查看系统版本:lsb_release -a [root@localhost /]# lsb_release -a *查看内核版本:uname -a *查看cpu型号:cat /proc/cpuinfo [root@localhost /]# cat ...
6111 0
|
9月前
|
人工智能 监控 中间件
如何用go语言实现类似AOP的功能
本文介绍了如何在 Go 语言中借鉴 Java 的 AOP(面向切面编程)思想,通过 Gin 框架的中间件和函数包装机制实现日志记录、权限校验等横切关注点与业务逻辑的解耦。内容涵盖 AOP 的优点、Go 中的实现方式、Gin 中间件与 AOP 的异同,帮助开发者提升代码模块化与可维护性。
325 0
|
12月前
|
存储 缓存 Java
【高薪程序员必看】万字长文拆解Java并发编程!(5):深入理解JMM:Java内存模型的三大特性与volatile底层原理
JMM,Java Memory Model,Java内存模型,定义了主内存,工作内存,确保Java在不同平台上的正确运行主内存Main Memory:所有线程共享的内存区域,所有的变量都存储在主存中工作内存Working Memory:每个线程拥有自己的工作内存,用于保存变量的副本.线程执行过程中先将主内存中的变量读到工作内存中,对变量进行操作之后再将变量写入主内存,jvm概念说明主内存所有线程共享的内存区域,存储原始变量(堆内存中的对象实例和静态变量)工作内存。
345 0
|
消息中间件 存储 运维
云消息队列 Kafka 版全面升级:经济、弹性、稳定,成本比自建最多降低 82%
本文介绍了阿里云云消息队列 Kafka 版的全面升级,强调了其在经济性、稳定性和弹性方面的显著提升。同时,与 Apache Kafka 相比,云消息队列 Kafka 版通过节省 66% 的资源,实现了客户使用成本比自建最多降低 82%。
770 119
|
安全 Java 测试技术
Java 模块化详解
Java 9引入了一项重要的功能:模块化(Module System)。模块化是一种将代码和资源封装到可重用和独立的单元中的方法,它有助于改善代码的可维护性、可重用性和安全性。本文将介绍Java模块化的基本概念、如何创建和使用模块以及一些最佳实践。
1159 0
|
自然语言处理 Java 程序员
java、八大经典书籍,你看过几本?
java、八大经典书籍,你看过几本?

热门文章

最新文章