戏说领域驱动设计(六)——限界上下文——设计
限界上下文(简称BC)是一个很难讲的部分。我寻思着是不是再多找一找文章,看看其它人怎么讲的,但犹豫再三还是决定按自已的理解去聊,各种找材料就有点剽窃的行为了。至于说的是否正确,您务必也要做好判断,毕竟每个人都会有自己的理解。做为温故而知新的一部分,在此把前面总结的BC的特点再重复一下,也不是为了凑字儿,DDD这东西就得靠多多的啰嗦才能记得住,毕竟概念忒多。此外,为提升您的阅读体验,限界上下文分为两节分别讲解。
BC的特点包括四个方面:1)是系统的物理划分;2)应根据子域的定义进行推导;3)限定了领域模型的边界,是对领域模型的一种划分和限定;4)BC内每个领域术语都有且只有一个明确的含义(即通用语言)。
BC的设计一般是通过子域进行推导。假如将DDD的指导分成三部分:子域设计、BC设计和代码设计,BC属第二层,起到承上启下的作用,在将业务模型转换为技术的过程中提供宏观指导。BC定义的过程其实就是确认有几个子系统(或Java中的包、.NET中的名称空间),有哪些领域模型(此处的领域模型是一种业务术语不是指‘类’或‘接口’)以及子系统间如何交互。从上述概念上可以看出来,讨论BC时既有业务的部分也有技术的内容。
领域模型 1、领域模型的使用贯穿了“分析”、“设计”、“开发”的整个流程,各类人员都应该使用领域模进行沟通和交流,避免系统在实现过程中需求走样 2、领域模型只反映业务与技术无关,其不仅包括业务中的实体如“订单”、“客户”等还包含业务流程如“下订单” 3、领域模型是有边界的,我们只应该关注业务所关注的部份 |
题外话:中国IT圈对一些词的翻译我觉得真是前无古人:句柄、多态、建模、闭包……这翻译,不服来战。
回到正题,在软件设计活动中(严谨的说是在UML建模过程中)包含三类模型:业务模型、分析模型和设计模型,具体解释如下列表。不过咱得多说一句,我们常见的类图啊、时序图啊,你可别认为这些模型仅用于实施前的设计阶段,在业务分析阶段也是可以用的,只是目的不一样。您可别回头一说类图就认为只在软件设计阶段专用,对外行说说就行了,内行咱得有内行的专业素养。
- 业务模型:用于解释与说明业务逻辑的各类文档或图,与是否有电脑无关系,是对客观的业务的描述。子域设计即是业务模型设计。
- 分析模型:用于说明哪些业务可在软件系统中实现(并非所有的业务都可被落实到软件中,这就是为什么常常见到开发与产品经理互撕),其上面连接了业务模型下面对应到设计模型。BC设计即分析模型设计。
- 设计模型:用于说明软件在代码层次上的设计方式,常见的如类图、活动图、时序图等。DDD战术阶段所建模型如聚合、实体即为设计模型。
上一章中展示了个人微信的域图,为避免误会本节以一款“即使通讯软件”的后端架构为例展示限界上下文的设计图,由于并无实际的软件,您仍可以微信为对照。我得先避个嫌疑,回头腾讯公司找过了就虾米了……另外,实际的系统架构比案例复杂的多的多,划分得也会更加的详细。此处仅做为引子告诉您如何进行BC设计,您在日常工作中需要学会举一反三,这也是治学问的正确姿势。时间久了,你就能体会何为“众里寻他千百度,蓦然回首,那人却在,灯火阑珊处”。
文章图片
为能说明问题,本例中把“小程序管理子域”和“鉴权子域”去掉了,图不好画(其实主要是影响您的阅读体验)。此外,上一章针对“通讯录子域”和“聊天子域”的设计不够细致,需要进行细化。下图为两个子域的细化结果,注意:此处的设计仍为子域图,尚未到BC设计阶段。
文章图片
文章图片
子域经过细化后我们建立了下面的BC图,需要注意的是BC设计图中应该以实线表示每一个限界上下文,因为BC具备物理特性已非概念上的模型, BC间的交互通过实线进行连接。
文章图片
BC的设计不仅需要子域设计为参考,还需要结合您的团队与公司的实际情况进行计。本案例的建设由同一部门的人数为200的成员所组成的团队,包括研发、测试、运维、产品经理、项目经理等基本角色,因资源充沛且岗位齐全,确定使用微服务架构作作为系统落地时的方案。我们来详细解释一下本方案的设计依据。
- 聊天子域:分为“通讯管理”和“历史消息管理”两个子系统,前者用于聊天场景比如发送各类文本、图片等;后者用于对历史消息进行存储以用于记录查询。这两个BC所关注的业务点有很大差异,边界较为明显,两个BC可使用不同的系统架构并可独立进化。
- 消息审计使用了第三方采购的实时审计系统用于对用户所发的朋友圈或消息进行审计以避免非法内容的存在。
- 通讯录子域分为两个BC:“联系人管理”和“好友关系管理”分别用于管理本账户的联系人和用于朋友推荐的推荐系统。
BC的设计粒度,往大了看其实可以是一个子系统本身,单体系统只有一个BC(此种情况下,单系统已经不能算是纯粹上的BC,应当以“包”或“名称空间”作为BC的基本单位);往小的方面看,最小的粒度为“聚合”,切记!真的不能再小了。无论其大小,关键的设计原则是“完整”即BC可以完整的支撑某项业务,换另外的说法就是每个BC应该是自治的且与其它BC有清晰的边界。实际上,当您在BC设计时会发现大部分情况下寻找BC边界是一个非常自然的过程,还是那句话:人是有灵性的。
注意! 系统的建设过程(开发阶段)中,请务必保证您的领域模型不能外泄到BC之外,这里的BC可以是一个项目也可以是一个包或名称空间。BC间的交互只能通过DTO或消息(其实消息也是一种DTO) |
- BC的设计是系统的宏观架构设计,一经确认后就需要以此为依据进行实施
- 以业务维度为准进行BC设计。这一条会存在例外:前后端分离架构,是一种比较典型的以技术为参照的的BC设计方式。就前端是否属于BC一部分的问题目前还是有一定的争议的,比较权威的书上的回答也是“Yes”,为此还引入了微前端的技术。我个人建议您视自己的公司与团队情况而定,不必拘泥于理论。
- BC设计需要以您的组织结构包括团队技术层次、团队组织结构、是否跨部门、人力资源情况等为参考以免虽有设计方案但无法落地,陷入纸上谈兵的境界,造成前期工作浪费。
- BC也需要保持随时变更,尤其是在子域有变更的情况下
- DDD中最为重要的规律是“运动与适应”,一切事务皆在变化中,您需要随时根据变化做调整
- 现实中,有些带头大哥喜欢根据开发任务来设计BC,这种情况最好少用以减少甩锅的情况。另外,个人建议BC的开发工作只由一个人负责即由上面的service到最下面的dao,不要针对同一个聚合让过多的人参与,每个人都有自己的设计思路,非常容易出现重复性的内容;一个研发人员的连贯性思路也很容易被打断。如果BC较大,也请限制在一个团队内以减少沟通成本
- 限界上下文的识别实际上并没有标准可言,可以通过业务复杂度、管理复杂度和技术复杂度去分析和识别,迭代化的进行分析 。
文章图片
依据上图所示的子域说明,推导出如下BC设计。
文章图片
不同于第一个案例,本例未使用微服务架构,而是使用了单体架构作为其落地方式。我知道有些人是强烈的微服务架构拥护者,但我仍然需要在此强调:系统的架构选择时,技术能力仅仅是一方面,而且还只是很小的一个方面。决策我们架构选择的因素有许多,比如团队的综合能力(注意:不能以团队中是否有一两个高手来决策团队综合能力)、团队结构、公司的总体结构(尤其您要做的系统是业务中台时)等。项目背景中已说明“开发兼职运维”,说明当前团队使用容器化部署、链路追踪、全栈监控等技术时会比较勉强,即使强加到系统中也会由于资源的不足造成您想要的结果与期望不匹配。
【戏说领域驱动设计(六)——限界上下文——设计】最后需要说一句,我们都知道微服务架构有各种优势,也知道单体系统有各种不足。但任何事务都有其两面性,在您使用的时候需要首先综合评估自身所具备的条件。再说了,您做的系统不是一锤子买卖,随着后续资源的投入,您是可以进行架构优化的。
推荐阅读
- 攻击Windows平台NVIDIA驱动程序
- 汇聚优质AR应用开发者,技术助力AR领域繁荣生态
- (世界经济论坛)8大因素或驱动Fintech颠覆金融业竞争格局
- Linux_drivers|基于linux的I2C驱动与调试(传统ID匹配方式)
- 两感一练
- GIS跨界融合赋能多领域技术升级,江淮大地新应用成果喜人
- 21天|21天|羊多多组合《书都不会读,你还想成功》
- 工业推荐领域与学术领域研究的方向差异
- 国家重点支持的高新技术领域(一)
- Spring注解驱动第十讲--@Autowired使用