解惑领域驱动设计的若干问题

简介: 解惑领域驱动设计的若干问题

最近重读Eric Evans的经典《领域驱动设计》,正如Eric提倡我们要去发现隐式概念一般,这次重读也让我发现了许多隐藏的DDD知识。恰好今日有朋友咨询我一些DDD问题,好似激活了触发器,随着问题的解答,我倒是在回答过程中又把这些知识梳理了一遍,才有了这篇杂记。


问题一:Repository的问题


怎么看待DDD中的Repository?我们必须把握一个根本的底线,就是采用DDD方式设计Repository时,一定要忘记所有与数据访问有关的技术实现细节。Repository接口属于领域层,一旦我们将Repository视为DAO对象,就会不期然地重回数据驱动设计的老路。

Eric在书中写道:“Repository将某种类型的所有对象表示为一个概念集合(通常是模拟的)”。这句话一语道破天机,也是DDD得名的由来,必须是通过领域去驱动设计,也就是说在这个设计过程中,应尽量去掉技术的色彩。

借用Martin Fowler对重构的隐喻,在领域驱动设计过程中,也有两顶帽子:领域设计与技术实现。在进行领域设计时,考虑的应该是领域逻辑、业务规则,以及随之需要设计演进的领域模型;一旦开始关注技术实现,就应该切换到与领域完全无关的技术关注点上。这也就是我认为非常关键的点:分离技术复杂度和业务复杂度。

Repository是一个概念集合,我们在领域设计时,又需要保证领域概念的完整性,并考虑领域逻辑的不变性约束,因此,DDD才会引入Aggregate。同时,DDD明确约定:一个Aggregate只能有一个Repository,即聚合根的Repository。所有对聚合的访问都应该通过Repository来完成。


问题二:针对没有采用DDD的项目,如何演化为DDD


在《领域驱动设计》的第四章”分离领域“,Eric给出了几点DDD的适用范围:

  • 领域驱动设计只有应用在大型项目上才能产生最大的收益,而这也确实需要高超的技巧。不是所有的项目都是大型项目;也不是所有的项目团队都能掌握这些技巧
  • 如果一个架构能够把那些与领域相关的代码隔离出来,得到一个内聚的领域设计,同时又使领域与系统其它部分保持松散耦合,那么这种架构也许可以支持领域驱动设计
  • 将领域实现独立出来是领域驱动设计的前提

因此,领域驱动设计绝对不是银弹,我们也不要将领域驱动设计视为拯救项目的灵丹妙药。从上述几点描述,我们似乎可以得出DDD的基础要素:

  • 项目的规模与领域复杂度
  • 项目成员的设计能力

当我们开始做一个新项目时,有可能从一开始业务并没有多复杂,系统规模也不够大,没有运用DDD是可以接受的选择。但随着需求的增加与变化,项目规模与领域复杂度都达到了DDD的要求。这时该如何应对?

针对这种已有的系统,若要从Non-DDD形式演化为DDD形式,无非是两种策略:

  • 策略一:对已有系统进行重构。注意这种重构并非Martin Fowler提出的代码级别重构,而是对领域模型的重构。如果没有领域模型,那么我们就需要去重新发掘领域知识,建立统一语言,进而提炼出领域模型,然后使用领域模型指导我们的程序设计。这时,需要重构已有代码来满足领域模型表达的知识。
  • 策略二:如果已有系统的功能与新需求存在一个清晰的边界,更简单的办法是将已有功能视为一个Bounded Context,然后对新需求采用DDD设计方法,并通过引入防腐层和已有系统进行通信。

倘若开启的新项目在领域复杂度上达不到DDD的要求,我仍然建议运用DDD,只不过需要将DDD的设计重点放在战略设计阶段,即对项目划分合理的Bounded Context。一旦确定了这些Context的边界,在边界之内进入战术设计阶段时,就可以不采纳DDD的设计方式,例如选择使用Transaction Script。


问题三:微服务与领域驱动设计的关系


领域驱动设计的战略设计可以帮助我们识别微服务的边界。针对微服务内部,可以采用DDD的方式,也可以采用其他方式,这个并没有特别约束。

大体可以这样认为:

  • 战略层面,领域驱动设计指导了微服务设计,微服务架构影响了领域驱动设计
  • 战术层面,二者没有任何关系,但DDD可以是微服务的其中一种实现

实践中,我们通常会使用DDD的Bounded Context、Context Map以及六边形架构来指导微服务设计。反过来,由于微服务强调服务的独立部署,因此微服务的引入重新定义了Bounded Context的边界,服务之间的通信也突破了Context Map的集成模式。

至于微服务对数据存储的设计约束——“每个微服务的数据单独存储”,属于基础设施层面,严格来讲,与领域驱动设计是没有任何关系的。

本文链接: http://zhangyi.xyz/solve-puzzle-of-ddd/

相关文章
|
存储 架构师 数据可视化
一文弄懂数据架构和信息架构的区别
我们经常会听到关于数据架构和信息架构的讨论,它们是一回事吗?让我们看看数据和信息之间的区别,以及组织需要考虑的关键事项。
一文弄懂数据架构和信息架构的区别
|
2月前
|
设计模式 架构师 Java
一文详谈领域驱动设计实践
本文作者结合在团队的实践过程,分享了自己对领域驱动设计的一些思考。
169 8
|
4月前
|
存储 领域建模 数据库
当谈论DDD到底在谈论什么
DDD领域驱动设计是将业务领域概念和规则映射到软件设计的方法,能打通产品、设计、编码人员的信息壁垒。同时一套设计保持了业务和编码的一一对应。
76 2
|
前端开发 JavaScript Java
|
存储 开发框架 Java
【领域驱动设计】三分钟搞懂领域驱动设计(一)
【领域驱动设计】三分钟搞懂领域驱动设计
|
存储 开发框架 Java
【领域驱动设计】大神三分钟搞懂领域驱动设计(上)
【领域驱动设计】大神三分钟搞懂领域驱动设计
|
架构师 算法 测试技术
小团队也能做DDD-中篇
小团队也能做DDD-中篇
241 0
|
Java 机器人 程序员
大白话DDD(DDD黑话终结者)
大白话DDD(DDD黑话终结者)
369 0
|
Web App开发 机器学习/深度学习 数据可视化
万字长文解析,领域驱动设计(DDD)落地设计
领域驱动设计(简称 ddd)概念来源于2004年著名建模专家Eric Evans 发表的他最具影响力的书籍:《领域驱动设计——软件核心复杂性应对之道》(Domain-Driven Design –Tackling Complexity in the Heart of Software),简称Evans DDD,领域驱动设计思想进入软件开发者的视野。在将近20年的发展中领域模型设计一直占据着非常重要的位置,但其直接面向业务场景的设计思想,更适合在具有特定业务场景的模型构建。
|
存储 前端开发 数据可视化
【领域驱动设计】三分钟搞懂领域驱动设计(二)
【领域驱动设计】三分钟搞懂领域驱动设计