解决DDD最大难题-如何划分领域
本文书接上回《反DDD模式之“复用”》,关注公众号(老肖想当外语大佬)获取信息:
最新文章更新;
DDD框架源码(.NET、Java双平台);
加群畅聊,建模分析、技术实现交流;
视频和直播在B站。
背景
最近直播的时候,看到一条留言,问我是否有关于如何划分领域的文章,翻看了一下,发现关于这么重要的问题,居然没有专门、认真、细致地讲过。也难怪不少人说不接地气,整天搞些虚头巴脑的东西。但没有讲的原因,我还是要为自己辩解几句的,不是不想讲,也不是不能讲,而是我潜意识里觉得本质的东西讲明白了,这个问题就太简单,没必要讲。
当然,如果你是我的老粉丝,关注过我过往输出的内容,那么你也知道,早前也是有在我们FireUG社区的DDD公开课里专门讲这个话题(【DDD 领域驱动设计 | PART V:如何识别领域边界?】 https://b23.tv/sRqAC8O )。
时至今日,我自己对于软件工程的认知又经过了一轮迭代,重新来解读一下这个问题。
先说答案
问:如何划分领域?
答:基于如下两条可以得出一个领域:
当你有一个需求,叫创建xxx时,那么这个xxx就是一个聚合根;
我们可以视作一个聚合根就是一个领域;
如何解读
例如,一个系统中,需要创建一个用户,那么用户就是聚合根,用户就是一个领域,诸如此类的需求是非常容易识别的,我相信不论你的软件设计经验如何,都是可以基于这个规则来做出判断的。
当然你会说,我有一个需求是给用户创建收货地址,那么这个收货地址是不是聚合根呢?这就要看,你创建的是“收货地址”,还是“用户的收货地址”,如果你认为是“收货地址”,那么它就应该是聚合根,如果你认为是“用户的收货地址”,意味着这个需求,仅仅是给“用户的收货地址属性”添加新值。

又比如订单,你是认为是“创建订单”还是“用户的订单”呢?我想大部分人会直觉上选择“创建订单”,为什么会有这样的直觉?我想,你一定会得出一个答案,“订单”足够复杂。
那么这样看来,理解业务的标准是不是又变成了“复杂的就分开”这么一个不太好衡量的判断呢?不妨你把它反过来看,就有答案了,那就是“简单的就合并”。

还是前面的例子,还是收货地址,因为存在一个需求叫“创建收货地址”或者“创建用户的收货地址”,我分不清楚,没关系,我们就默认视作存在这个聚合根,存在“收货地址”这个领域。然后我们在考虑,这个领域独立存在对我们有没有好处,这个领域合并进“用户”领域,我们是否可以接受。如果我们有充分的把握说合并没有问题,那么就合并,否则,就让它成为一个领域,并保持边界明确。
为什么基于创建xxx来判断
也许,你会有疑问,为什么基于“创建xxx”需求来判断聚合根?核心逻辑就是这类需求,意味着xxx不可分割的整体,意味xxx就是最小的完整范围,相当于我们基于这类需求,识别出了系统内的“原子单元”,就像一片片乐高积木一样,不可再拆分。
本质是什么
在我看来,这样划分领域的方法的本质,就是我们先认为边界就在那里,凡是有创建xxx的需求,即存在一个领域,只是说我们经过思考,某些领域合并进去是比较确定复杂度是可以掌控的,那么我们才做出了合并领域的决定。
所以,与其说这是如何划分领域,不如说,这是思考什么时候合并领域。

底层价值观的支撑
如果你是跟随本系列文章一路阅读过来的话,一定知道,我对于软件设计的核心观点是:
DDD是一种价值观
保持边界明确是最重要的事
那么你就会发现,前面说的方法,是完全契合这个价值观的,我们首先明确出组成系统的一个个“原子单元”,识别出它们,然后再谨慎地进行合并,在没有把握的情况下,优先保持领域边界明确,避免它们之间的耦合。
而信奉这个价值观的依据则是我们对于复杂度的理解,这在前文也有详细讲解:
系统复杂度与元素的数量和元素的关系有关;
元素的关系对系统复杂度的影响远远大于元素的数量所产生的影响;
说到底,核心目的仍然是为了保持我们对系统复杂度的掌控,因此我们谨慎地为系统内的领域之间“建立耦合”。
完整操作方法
那么,如果你和我一样,认同DDD是价值观,保持边界是最重要的事,我们完整的操作方法就是:
当你有一个需求,叫创建xxx时,那么这个xxx就是一个聚合根;
我们可以视作一个聚合根就是一个领域;
当我们非常大把握可以掌控一个领域合并后的复杂度时,可以考虑合并这两个领域;
结尾
以上就是我们团队日常分析需求、设计方案和建模的实际操作方法,如果你赞同或者有共鸣,也很期望您将文章分享给更多的朋友。如果你持有不同的观点和视角,也欢迎与我讨论,我相信,至少持续提升开发者幸福感这个方向,咱们是有共识的。
解决DDD最大难题-如何划分领域的更多相关文章
- DCI架构是如何解决DDD战术建模缺点的?
摘要:将DCI架构总结成一句话就是:领域对象(Object)在不同的场景(Context)中扮演(Cast)不同的角色(Role),角色之间通过交互(Interactive)来完成具体的业务逻辑. 本 ...
- 十年磨一剑,王坚自研的MaxCompute如何解决世界级算力难题
摘要: 2009年这项关于大数据的技术长征开始.王坚带队,目标是自研大数据计算平台MaxCompute统一阿里巴巴内部的数据和大数据计算体系. 大数据时代,随着企业数据规模的急剧增长,传统软件已无法承 ...
- indexDB解决过的难题
我第一次使用indexDB是1年前(2018年10月),运用这个黑科技,解决过3个异常棘手的问题(如果不是indexDB 几乎找不到其他解决方案)所以我经常强调,前端一定要学indexDB! 难题一: ...
- [思维提升|干货All in]6种算法解决LeetCode困难题:滑动窗口最大值
为了更好的阅读体验,欢迎阅读原文: [思维提升|干货All in]6种算法解决LeetCode困难题:滑动窗口最大值 (eriktse.com) 最近在leetcode遇到一道非常经典的题目:239. ...
- DDD划分领域、子域,核心域,支撑域的目的
名词解释 在DDD兴起的原因以及与微服务的关系中曾举了一个研究桃树的例子,如果要研究桃树,将桃树根据器官分成根.茎.叶.花.果实.种子,这每一种器官都可以认为是一个研究领域,而领域又有更加具体的细分, ...
- 从壹开始微服务 [ DDD ] 之三 ║ 简单说说:领域、子域、限界上下文
前言 哈喽大家好,DDD领域驱动设计系列又开始了,前天周二的那篇入门文章中,也收到了一定的效果(写小说的除外),同时我也是倍感鸭梨,怎么说呢,DDD领域驱动设计已经有十年历史了,甚至更久,但是包括我在 ...
- 使用prolog逻辑语言解决爱因斯坦斑马难题
如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...
- 七周七语言之使用prolog解决爱因斯坦斑马难题
如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...
- 解决大数据难题 阿里云MaxCompute获科技大奖
摘要: 据介绍,MaxCompute(大规模分布式的数据计算平台)是国内最早自研的大数据计算平台之一,主要应用于大规模数据处理场景.目前,这项源自浙江.解决世界级难题的成果已拥有EB(百京)级别的数据 ...
- 深入super,看Python如何解决钻石继承难题 【转】
原文地址 http://www.cnblogs.com/testview/p/4651198.html 1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...
随机推荐
- 基于docker搭建单机测试ELK
说明:本次使用的windows系统,利用vm进行安装虚拟机,安装的只是单测试单机版elk. 一.下载vm 自行官网下载 二.安装centos7系统 自己有现成的镜像跳过,没有自行查找资料完成 三.进行 ...
- 中考游记 & 暑假集训大记
中考游记 & 暑假集训大记 前言 如今已经回归 \(OI\) ,望着如烟的往事,或是将将知道的讯息,心中早是凄然. 我真的希望这世间有我所期望的浦岛隧道,带回所有的遗憾,同时带走迷茫与害怕,重 ...
- 我的微服务项目之IdentityServer4
2021,祝大家新年快乐!!! 2021年了,新的一年应该有新的计划,我的计划是准备去学习微服务,所以我将我自己的博客项目拆分成了一个微服务项目,用来给自己学习,项目地址:http://www.tt ...
- Oracle导出数据库与还原
导出部分 1.获取到Oracle directory目录与实际电脑目录的映射 2.CMD导出Oracle数据库 DMP文件 //expdp 用户/密码@数据库监听地址 schemas=表空间名称 du ...
- MRI roi图像合并
笔记来源:MRI roi的图像合并 dpabi小工具_哔哩哔哩_bilibili 1. 如果几个图像的维度不一致,需要先进行reslice 1)如何看图像的维度 以软件MRIcron为例, windo ...
- JavaScript Library – YouTube Embedded、YouTube Player API、YouTube Data API
YouTube Embed Video 参考: Embed videos & playlists 它和 Google Maps Embed 类似,是通过 iframe 完成的. <ifr ...
- CSS – W3Schools 学习笔记 (3)
CSS Rounded Corners Link to W3Schools 它是用来画圆角的, 假设有 1 给正方形, 100px. border-top-left-radius: 30px; bef ...
- 基于Tauri2+Vue3搭建桌面端程序|tauri2+vite5多窗口|消息提醒|托盘闪烁
基于tauri2+vite5+vue3封装多窗口实践|自定义消息提醒|托盘右键菜单及图标闪烁 这段时间一直在捣鼓最新版Tauri2.x整合Vite5搭建桌面端多开窗体应用实践.tauri2.0相较于1 ...
- QT硬件异构计算
QT硬件异构计算 使用AI技术辅助生成 1 QT硬件异构计算概述 1.1 硬件异构计算概念 1.1.1 硬件异构计算概念 硬件异构计算概念 <QT硬件异构计算>正文 硬件异构计算概念 在进 ...
- FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播
之前的文章<利用RTMP协议构建电脑与手机的直播Demo>介绍了如何使用RTMP Streamer实现完整的RTMP直播流程,另一篇文章<利用SRT协议构建手机APP的直播Demo ...