讲DDD之前,咱们得了解一些基本概念,大家都知道DDD指的是领域驱动设计(Domain-Driven Design),那怎么理解DDD呢?
- 战略设计:业务层面的领域建模,它强调业务领域模型的识别与边界划分,简单来说就是业务设计,与代码呈现无关;
- 战术设计:工程层面的架构设计与模型设计,具体应用到微服务就是完成微服务设计。
- 通用语言:它的作用是定义上下文含义,以便限界上下文定义领域边界
- 事件风暴:由项目团队、领域专家等多人参与,采用头脑风暴的方式进行用户故事分析,找出并建立领域对象
- 四色建模:按时间发展先后顺序,识别“追溯单据”作用的“时标”概念,直达业务核心数据;它强调可追溯性与执行效率
- 限界纸笔建模:回到一百年前,在一个我们没有计算机的年代,我们要做业务设计会用什么方法呢?我们可以用纸和笔画表格并写实例,管理核心领域“恰好够用”的数据,增强数据完整性,避免过度设计
- DCI建模:可能DCI我们听得比较少,其实DCI架构与MVC架构的提出者是同一个人。DCI建模通过角色扮演模型使得领域模型易于理解,通过小类大对象的手法避免上帝类的问题;同时它也能解决贫血模型和充血模型之争,使模块更加高内聚、低耦合;当然,DCI建模也可以与四色建模融合使用
那么,领域驱动战术设计应该如何落地呢?我认为,考虑两个大方向即可:
- 模型设计:比如,使用充血模型还是贫血模型
- 架构设计:比如,DDD/CQRS、整洁架构、六边形架构、清晰架构、DCI架构……
至此,我们了解清楚了DDD的一些基本概念,那DDD为什么对我们如此重要呢?
- 从业务领域视角划分领域边界,构建通用语言进行高效沟通,降低团队新成员对业务的熟悉成本
- 在不断交流的过程中,通过提炼领域概念与业务抽象建立领域模型,维持业务和代码的逻辑一致性
- 通过对领域模型归类与行为分析,保证实现业务的准确性
- 领域建模比数据库建模更轻更全面,而数据库建模不能完全反映系统的全部特性和需求
DDD指导落地:
- 不过分依赖系统设计人员的经验背景,指导表设计、代码落地
- 指导微服务的设计和拆分——划分出清晰的微服务边界、可持续演进的微服务架构
简易维护:
- 从讨论、设计,到评审、落地,以领域模型进行交流,可作为系统业务的核心载体
- 以微服务的维度划分限界上下文,服务拆分只需要把相应的限界上下文拆出去即可
- 减少因业务需求迭代(如:模型变更)带来的维护成本
这就是DDD对我们的重要意义,我们不能只以开发视角去看待业务问题,那样的话就会陷入开发思维陷阱,这对我们的业务成长没有任何帮助。
领域(Domain)
领域是指在特定的范围或边界内要解决的业务问题域,它的核心思想是将业务问题域逐级细为子域/核心域/通用域/支撑域,降低业务理解和系统实现的复杂度。
聚合(Aggregate)
值得注意的是,一个微服务最小不要小于一个聚合,避免引入分布式事务的复杂度。
限界上下文(Bounded Context,简称BC)
- 领域发现:难点在于领域模型的概念提炼、模型分析与归类;
- 领域划分:难点在于业务边界和应用边界如何清晰划分,如何把控业务设计的粒度,是自底向上归纳划分还是自顶向下演绎划分;
- 领域建模:难点在于如何识别聚合、聚合根、实体、值对象,如何确立领域模型之间的关系与核心交互等等。
在我们接到需求的时候,会在脑子里把实现的代码过一遍,这对于简单的CRUD来说并不难,但是涉及到更复杂的业务,一个场景就够我们沟通很久才能说清楚,那怎么办呢?
- 建立时标原型:寻找需要追溯的事件,根据追溯事件寻找足迹
- 建立PPT原型:丰富模型,寻找时标原型周围的人/事/物,使它可以更好地描述业务概念
- 建立角色原型:进一步从中抽象出可以参与到不同流程中去的角色
- 建立描述原型:把一些信息用描述对象补足
这里咱们需要注意的是,整个过程会穿插着原型之间关系/核心交互的标注。
我们来看一幅电商DDD的四色图案例:
如下图所示,这是财务领域模型和支付中心模型的一部分,这里只描述了业务系统是如何运作起来的,并没有涉及表的具体字段设计,全量的模型图因涉及敏感信息不作详细展示:
领域建模就是这么个建模,这里我提一些设计细节:
- 粉红色指的是时标原型,是核心业务产生的数据,基本上对应表设计
- 模型属性不需要体现表的审计字段,比如通用的ID、创建者、修改时间、软删除标识等,模型行为也只需要设计核心行为即可,那种约定俗成的CRUD方法就不需要写出来了,设计要懂得取舍
- BC内模型除了依赖、聚合等等连线,可使用箭头连接模型之间的核心交互,跨BC之间的模型使用虚线箭头连接,这里我是结合了DCI建模法(D表示数据,C表示上下文、场景,I表示模型间的交互)
- 对于表示业务唯一的属性,我使用了加粗展示,再也不用跟别人费劲去解析这些模型是用什么维度去建的了
- 对于还没上线的属性变动(新增/修改),使用红色标记,因为领域模型图是指导我们业务开发的
- 限界上下文的划分是一种非常主观的边界划分,为了后续代码能够灵活调整,在Controller的URL设计里不需要加上限界上下文
领域模型图就像代码一样,需要我们长期去维护的,不是说做完设计就不去管了,这一点很重要,微服务负责人一定要有这个意识。
本文仅供学习!所有权归属原作者。侵删! 来源:搜狐技术产品