首页 > 其他分享 >解决DDD最大难题-如何划分领域

解决DDD最大难题-如何划分领域

时间:2024-11-06 20:58:08浏览次数:3  
标签:难题 收货 创建 xxx 地址 领域 划分 DDD

本文书接上回《反DDD模式之“复用”》,关注公众号(老肖想当外语大佬)获取信息:

  1. 最新文章更新;

  2. DDD框架源码(.NET、Java双平台);

  3. 加群畅聊,建模分析、技术实现交流;

  4. 视频和直播在B站。

背景

最近直播的时候,看到一条留言,问我是否有关于如何划分领域的文章,翻看了一下,发现关于这么重要的问题,居然没有专门、认真、细致地讲过。也难怪不少人说不接地气,整天搞些虚头巴脑的东西。但没有讲的原因,我还是要为自己辩解几句的,不是不想讲,也不是不能讲,而是我潜意识里觉得本质的东西讲明白了,这个问题就太简单,没必要讲。

当然,如果你是我的老粉丝,关注过我过往输出的内容,那么你也知道,早前也是有在我们FireUG社区的DDD公开课里专门讲这个话题(【DDD 领域驱动设计 | PART V:如何识别领域边界?】 https://b23.tv/sRqAC8O )。

时至今日,我自己对于软件工程的认知又经过了一轮迭代,重新来解读一下这个问题。

先说答案

问:如何划分领域?

答:基于如下两条可以得出一个领域:

  1. 当你有一个需求,叫创建xxx时,那么这个xxx就是一个聚合根;

  2. 我们可以视作一个聚合根就是一个领域;

如何解读

例如,一个系统中,需要创建一个用户,那么用户就是聚合根,用户就是一个领域,诸如此类的需求是非常容易识别的,我相信不论你的软件设计经验如何,都是可以基于这个规则来做出判断的。

当然你会说,我有一个需求是给用户创建收货地址,那么这个收货地址是不是聚合根呢?这就要看,你创建的是“收货地址”,还是“用户的收货地址”,如果你认为是“收货地址”,那么它就应该是聚合根,如果你认为是“用户的收货地址”,意味着这个需求,仅仅是给“用户的收货地址属性”添加新值。

又比如订单,你是认为是“创建订单”还是“用户的订单”呢?我想大部分人会直觉上选择“创建订单”,为什么会有这样的直觉?我想,你一定会得出一个答案,“订单”足够复杂。

那么这样看来,理解业务的标准是不是又变成了“复杂的就分开”这么一个不太好衡量的判断呢?不妨你把它反过来看,就有答案了,那就是“简单的就合并”。

还是前面的例子,还是收货地址,因为存在一个需求叫“创建收货地址”或者“创建用户的收货地址”,我分不清楚,没关系,我们就默认视作存在这个聚合根,存在“收货地址”这个领域。然后我们在考虑,这个领域独立存在对我们有没有好处,这个领域合并进“用户”领域,我们是否可以接受。如果我们有充分的把握说合并没有问题,那么就合并,否则,就让它成为一个领域,并保持边界明确。

为什么基于创建xxx来判断

也许,你会有疑问,为什么基于“创建xxx”需求来判断聚合根?核心逻辑就是这类需求,意味着xxx不可分割的整体,意味xxx就是最小的完整范围,相当于我们基于这类需求,识别出了系统内的“原子单元”,就像一片片乐高积木一样,不可再拆分。

本质是什么

在我看来,这样划分领域的方法的本质,就是我们先认为边界就在那里,凡是有创建xxx的需求,即存在一个领域,只是说我们经过思考,某些领域合并进去是比较确定复杂度是可以掌控的,那么我们才做出了合并领域的决定。

所以,与其说这是如何划分领域,不如说,这是思考什么时候合并领域。

底层价值观的支撑

如果你是跟随本系列文章一路阅读过来的话,一定知道,我对于软件设计的核心观点是:

  1. DDD是一种价值观

  2. 保持边界明确是最重要的事

那么你就会发现,前面说的方法,是完全契合这个价值观的,我们首先明确出组成系统的一个个“原子单元”,识别出它们,然后再谨慎地进行合并,在没有把握的情况下,优先保持领域边界明确,避免它们之间的耦合。

而信奉这个价值观的依据则是我们对于复杂度的理解,这在前文也有详细讲解:

  1. 系统复杂度与元素的数量和元素的关系有关;

  2. 元素的关系对系统复杂度的影响远远大于元素的数量所产生的影响;

说到底,核心目的仍然是为了保持我们对系统复杂度的掌控,因此我们谨慎地为系统内的领域之间“建立耦合”。

完整操作方法

那么,如果你和我一样,认同DDD是价值观,保持边界是最重要的事,我们完整的操作方法就是:

  1. 当你有一个需求,叫创建xxx时,那么这个xxx就是一个聚合根;

  2. 我们可以视作一个聚合根就是一个领域;

  3. 当我们非常大把握可以掌控一个领域合并后的复杂度时,可以考虑合并这两个领域;

结尾

以上就是我们团队日常分析需求、设计方案和建模的实际操作方法,如果你赞同或者有共鸣,也很期望您将文章分享给更多的朋友。如果你持有不同的观点和视角,也欢迎与我讨论,我相信,至少持续提升开发者幸福感这个方向,咱们是有共识的。

标签:难题,收货,创建,xxx,地址,领域,划分,DDD
From: https://www.cnblogs.com/xiaoweiyu/p/18531028

相关文章

  • 难题
    难题题意定义\(f(i)\)为非\(i\)因数的最小正整数,给出\(n\),求\(\sum_{i=1}^{n}f(i)\bmod10^9+7\)。思路显然\(f(i)\ge2\)。若\(f(i)=x\),则\(f(i)\)一定为\(\text{lcm}(1,2,\dots,x-1)\)的倍数,但不是\(\text{lcm}(1,2,\dots,x)\)的倍数。可以枚举\(x\),统......
  • 手把手教你在家中免费搭建自己的电视直播源服务器!从此告别直播源的难题!(支持群晖、飞牛
    文章目录......
  • 内存为什么要划分堆区、栈区?除了堆栈之外内存还有什么分区?
    最近在学习计算机底层相关的知识,看到内存这块内容时有个疑问,为什么要提出堆、栈的概念?当初是为了解决什么问题呢?除了堆栈外内存还存在其他分区吗?大学里学过微机原理涉及到一些相关内容但是到如今已经忘得差不多了。还是重新找资料记录一下学习过程吧!堆、栈的提出计算机在最开......
  • HyperWorks二维网格划分及拓扑改进
    Step01:载入模型Exercise_3a.hm。Step02:2D网格划分。(1) 进入automesh面板。图3-13设置automesh面板网格控制参数 (2)指定elementsize为5,根据图3-13设置网格控制参数。(3)查看网格。图3-14新创建的网格模型 网格模型整体看来比较理想,但局部放大......
  • 【解决MongoDB安装难题!】计算机丢失VCRUNTIME140D.dll?一招教你快速修复!
    在安装或运行Java的MongoDB相关程序时,如果遇到“无法启动此程序,因为计算机丢失VCRUNTIME140D.dll”的错误,通常是由于缺少MicrosoftVisualC++Redistributable包。VCRUNTIME140D.dll是VisualC++2015-2019Redistributable的一部分,用于支持C++应用程序的运行时库。以下是解......
  • HyperWorks二维网格划分与单元连续性
    自动网格划分HyperWorks中为零件定义几何曲面是创建零件壳单元网格的最佳方式。HyperMesh创建二维网格最有效的方法是使用Automesh面板直接在零件的表面创建网格。Automesh面板是HyperMesh重要的网格划分工具,通过automesh可实现单元尺寸、单元密度、单元类型以及节点分......
  • 代码复用:DDD视角下的平衡艺术
    代码复用:DDD视角下的平衡艺术https://mp.weixin.qq.com/s/5gIBJByRZfNPbh6yjAvj9w代码复用:DDD视角下的平衡艺术原创 杜沁园(悬衡) 阿里技术 2024年10月11日08:31 浙江  这是2024年的第76篇文章(本文阅读时间:15分钟)01引言刚工作时,代码写得不太好,师兄每次CR代......
  • 为什么我越来越喜欢用DDD — DDD架构篇(1)
    HelloDDDDDD是一种软件设计方法,DDD是指导我们做软件工程设计的一种手段。它提供了用切割工程模型的各类技巧,如;领域、界限上下文、实体、值对象、聚合、工厂、仓储等。通过DDD的指导思想,我们可以在前期投入更多的时间,更加合理的规划出可持续迭代的工程设计。在DDD中有一套......
  • 代码随想录算法训练营day30| 452. 用最少数量的箭引爆气球 435. 无重叠区间 763.
    学习资料:https://programmercarl.com/0452.用最少数量的箭引爆气球.html重叠区域问题最远位置问题452.用最少数量的箭引爆气球(重叠区域;按左边界排序;i区间的左边界与i-1区间的右边界比较来确定是否重叠;更新i的右边界,取i与i-1区域右边界的最小值)点击查看代码classSolution(ob......
  • 双11场景下的精准营销难题,火山引擎数据飞轮给出这份解答
    10月14日,阿里巴巴、拼多多、京东选择在同一天启动双11;而在更在之前,抖音、小红书已有动作——前者在国庆假期刚结束就开启“抖音商城双11好物节”,后者则在12日宣布启动“1年1读购物狂欢”。 今年,似乎将成为“史上最长双11”。 “战线”拉长了,但从预售期的表现来看,各大平台的......