领域驱动设计随感录

2023-03-23 16:52:29 浏览数 (2)

本文内容来自我发表在知识星球[NoDDD]中的一些片段感想,随手而记,记录思想片段,皆是针对领域驱动设计的感悟,因为不成体系,故而名为随感录。

1

有时候在技术上确定限界上下文的边界反而是一件容易的事,不过就是按照DDD的设计思想依势而为罢了。虽然有by experience的因素,然则好歹是架构师可以掌控的。

真正难以控制边界的,其实是团队的边界和思维的边界。

要让团队成员能够放开自己的利己主义思想,愿意站在项目层次的高度看待工作边界,真的是太不容易了。如果团队来自不同的公司,就更是困难,对工作边界的划分会不断陷入到争吵、推诿、扯皮的泥潭中,最终还是走上各行其是的道路。很多时候,无论召开多少次协调会议,都不顶用。

要控制思维的边界,那简直就是天方夜谭了。团队成员不愿意改变固有的思维,不愿意接受新的思想方法,你怎么样推动、解释、演示和培训都没有作用,尤其对于那些已经习惯了惯性思维、乐于停留在舒适区的人而言。

2

统一语言是团队各个角色达成正确且一致的业务语言。它不仅仅是语言,还是原则,是团队在描述领域知识时必须遵守的最高原则。领域知识包括领域概念、领域行为和领域规则。统一语言是DDD中唯一一个贯穿问题空间和解空间的原则。统一语言可以表现为自然语言、文档、UML图,但最终要通过代码来呈现。

3

DDD战术设计的三个要点:

  • DDD强调领域建模,无论是设计还是开发,要从业务角度出发,而不能从数据库角度出发。先定义领域模型,然后再根据领域模型设计数据模型。我所说的数据模型是指数据库表的设计(schema),在DDD中,并不要求定义专门的数据模型对象与数据表对应,领域模型对象自身就扮演持久化对象的角色。
  • Eric Evans的DDD是以OO编程范式为核心,所以任何战术设计的点,都要围绕着面向对象的思想来考虑。为什么DDD不赞成贫血模型?就是因为贫血模型与OO设计思想相悖。为什么不建议用基本类型?因为它缺乏对领域概念的封装。
  • Eric Evans的DDD非常强调Aggregate,我认为这是战术层面上Eric的重要创见,因为它在设计层面多引入了一个边界概念。这个边界概念大于类、小于模块,恰恰是与所谓的“不变量(invariant)”(即一致性)刚刚对应起来。当然,这也是在战术设计层面DDD建模不同于OO建模之处。

4

如何在纷繁复杂的业务需求描述中,找到合适而准确的领域概念?个人经验,建模者需要具备以下能力:

  • 抽象能力:要学会从具体的事物中识别共性特征,然后用相对抽象的领域概念描述。
  • 精炼能力:提炼出来的领域概念首要是准确,然后在准确的基础上,尽量保障概念的简短(英语来表现),不要画蛇添足地为领域概念增加诸如Data、Info、Record之类的后缀。例如在仓储管理中,需要用到拣货记录这一领域概念,若直译为英文,为PickingRecord或PickingList,然而在亚马逊的仓储模型中,却直接使用了一个精炼的Pick来代表此概念。
  • 学会行话:深挖行业的领域知识,要用该行业的行话来表现领域概念,尤其是了解国外行话与国内行话的区别,并为之建立映射关系。例如金融行业有一个行话是“头寸”,源自民国期间作为货币的“袁大头”每十个摞起来为一寸,与之映射的英文描述则是Position,表示个人或实体持有或拥有的特定商品、证券、货币等的数量。
  • 学会隐喻:学会给一些相对抽象又无以名之的领域概念打比方,只要找到了那个准确的隐喻,不妨将其放到团队需要维护的统一语言中。例如,我在一个培训项目中,使用Ticket表示分配给员工的一次培训机会;在一个报表工具中,我使用了画布(Canvas)代表报表的视图,因为数据可以通过Painter写入到画布上,而Painter实际上是对输出功能的隐喻。

5

DDD要实施成功,一个必要条件是整个团队都要按照DDD的方式开展,也就是遵守DDD纪律。

为了降低对成员能力的要求,我对DDD的一些实践做了简化,主要的简化就是围绕业务服务提出:

  • 菱形对称架构:面向战略架构
  • 服务驱动设计:面向领域建模

在实施DDD过程中,由于成员能力参差不齐,我的要求是:

  • 对于设计和编码突出的成员,可以打破设计方法和模式的约束,除此之外,其他成员需要严格遵循原则。

6

今天回答读者群的一位群友问题,他苦恼于在针对业务进行建模时,设计UML找不到北。如他自己所说:“我清楚应该站在业务的层次去设计,但是我设计出来的UML感觉总是差点意思,技术体现太多了”。他问我:“虽然我知道是咋回事,但是我就是表达不出来。这种毛病有没有什么方法能解决?”

我的回答:

就像张三丰教张无忌太极剑一样,你需要学会忘记技术实现。就是从纯业务的角度去考虑。我的书中将整个领域建模分为三个过程:

  • 领域分析建模:只做业务分析
  • 领域设计建模:引入DDD的设计元素
  • 领域实现建模:通过TDD驱动实现

我用一个形象的比喻来形容这三个过程:

  • 第一个过程,你还是单身狗,目的就是找对象,也就是找出业务中的领域概念
  • 第二个过程,你谈恋爱了,需要你有理智地搞对象,弄清楚对象之间的关系
  • 第三个过程,你成家了,须得考虑油盐酱醋茶,也就是考虑基础设施的实现

0 人点赞