DDD 实战分享 - 消息中心

DDD 解决什么问题/为什么要用 DDD
DDD 整体流程(来源 ThoughtWorks)
v1

v2

最大的区别在于第一步的事件风暴与换成了战略设计的识别核心域。个人觉得对于新业务不够熟悉的情况下不适合提前讨论核心域,因为没有掌握足够信息全靠猜测,前期过多讨论浪费时间。
个人理解的 DDD 流程
前期价值、痛点、需求
事件风暴识别事件命令领域名词
业务建模/战略设计(开发与业务的建模)划分子域/核心域限界上下文建立业务模型
模型设计/战术设计(开发之间的建模)模型设计 api 设计分层架构数据库设计代码编写发布
上一层的输出是下一层的输入。
DDD 战术设计相关概念

DDD 四层结构

DDD 各层流通对象(消息中心现状)



DDD 代码目录
server 接口层
application 应用层
domain 领域层
infra 基础设施层
一个微服务存在多个限界上下文,domain 层的下层目录是指限界上下文的划分。其他 infra/persistent、server、application 层的下层目录是按模块分包。按模块+限界上下的设计是为了解决每个上下文四层目录设计的落地成本的折中方案。按模块分包的好处是解决了领域名词冲突。比如上下文 A 存在 category 聚合和上下文 B 可能存在 category 聚合的同名冲突。
粒度划分:领域>子域>限界上下文>聚合>聚合根/实体/值对象
Go GRPC DDD 框架

Go GRPC DDD 框架详细目录说明
PHP BFF 目录结构

proto 目录


BFF 按限界上下文划分模块、proto 也按限界上下文分包
案例讲解
根据战略设计划分出来的消息中心业务模型

下文对产品上下文的实现做分析。
战术设计-产品上下文的模型设计

api 设计
BFF

GRPC

GRPC-Gateway

设计之初不太建议限界上下文名称和聚合名称同名;接口路径按照:“限界上下文/聚合/行为”定义。
BFF 获取产品应用 APIDOC 定义
可以看到,这个接口需要产品聚合和应用聚合组合出来的数据。由于组合出来的对象无法归属到产品实体和应用实体的任何一个,是两个领域对象的组合体,需要有一个对象来装载,这个对象就是 BO(业务对象)。
类比微服务,微服务只负责本微服务内的领域,聚合只负责本聚合的实体。DDD 的核心就是边界划分清晰。
下图是应用层的服务编排

应用和场景的聚合设计



使用了 golang 继承的方式实现实体定义,减少结构体繁琐的定义。与传统表模型不同的是,DDD 实体是表模型的抽象,一个实体可能由多个表模型组合而成,当然这多个表模型要归属一个聚合下的。本例中,应用和场景组成了一个实体,应用是聚合根(主实体),场景是实体,聚合根是与外部对象沟通的代表,非主实体的业务操作需要通过聚合根来完成,如想要修改或查看应用场景,要经过应用聚合来操作:
而不是弄个场景服务来操作
聚合理念参考文章:深入理解DDD的聚合模式
DDD 各层流通对象(推荐版)


问题
事务
其他



从 DDD 可以学习那些思维模型
分层思维
“计算机领域的任何问题都可以通过增加一个间接的中间层来解决”

归类思维
对于众多问题,如何减少解决问题数量的数量,可以归类处理。如:
如何赚一个亿
如何保持身体健康
如何提高表达能力
如何实现财富自由
如何找到女朋友
如何拥有幸福的家庭
如何高效工作
如何高效沟通
如何带小孩
怎么提高自己的写作技巧
什么样的运动最健康
跑步怎么跑
问题域归类

也可以更加抽象,抽象层次越高,视野越宽广,需要考虑的问题越多。

边界思维
举例:公司组织架构分部门/小组
版权声明: 本文为 InfoQ 作者【麦麦】的原创文章。
原文链接:【http://xie.infoq.cn/article/83e26d4c43e6bb076c2e6ca20】。文章转载请联系作者。
评论