对比常规MVC三层架构中,我们进行功能开发的时候,拿到需求,解读需求。最先做的一步是设计表结构,在逐层设计上层dao,service,controller。对于产品或者用户的需求都做了一层自我理解的转化。
用户需求在被提出之后经过很多层转化后,特别是研发需求在数据库结构这一层转化后,将业务以主观臆断行为进行了转化。一旦业务边界划分模糊,考虑不全。大量的逻辑补充堆积到了代码层实现,变得越来越难维护。
- 消除消息不对称
- 常规MVC三层架构中自底向上的设计方式做了一个反转,以业务为主导,自顶向下的进行业务领域划分
- 将大的业务需求进行拆分,分而治之
对于DDD与常见MVC架构的区别。这里以电商订单场景为例。假如我们现在要做一个电商订单下单的需求。涉及到用户选定商品,下订单,支付订单,对用户下单时的订单发货。
MVC架构里面,我们常见的做法是分析好业务需求之后,就开始设计表结构了,订单表,支付表,商品表等等。然后编写业务逻辑。这是第一个版本的需求,功能迭代,订单支付后我可以取消,下单的商品我们退换货,需要进行加表,紧接着对于的实现逻辑也进行修改。功能不断迭代,代码就不断的层层往上叠。
DDD架构里面,我们先进行划分业务边界。这里面核心是订单。那么订单就是这个业务领域里面的聚合逻辑体现。支付,商品信息,地址等等都是围绕着订单。订单本身的属性决定之后,类似于地址只是一个属性的体现。当你将订单的领域模型构建好之后,后续的逻辑边界与仓储设计也就随之而来了
- 面向对象设计,数据行为绑定,告别贫血模型
- 降低复杂度,分而治之
- 优先考虑领域模型,而不是切割数据和行为
- 准确传达业务规则,业务优先
- 代码即设计
- 它通过边界划分将复杂业务领域简单化,帮我们设计出清晰的领域和应用边界,可以很容易地实现业务和技术统一地架构演进
- 领域知识共享,提升协助效率
- 增加可维护性和可读性,延长软件生命周期
- 中台化的基石
战略设计:限界上下文、通用语言、子域
战术设计:聚合、实体、值对象、资源库、领域事件、模块
限界上下文是一个显式的语义和语境上的边界,领域模型便存在于边界之内。边界内,通用语言中的所有术语和词组都有特定的含义。
通用语言就是能够简单、清晰、准确描述业务涵义和规则的语言。
把限界上下文拆开来看。限界就是领域的边界,而上下文则是语义环境。通过领域的限界上下文,我们就可以在统一的领域边界内用统一的语言进行交流。
域是空间问题,限界上下文是解决空间。
防腐层简称ACL,在集成两个上下文,如果两边都状态良好,可以引入防腐层来作为两边的翻译,并且可以隔离两边的领域模型。
DDD中要求实体是唯一的可持续变化的。意思是说在实体的生命周期内,无论其如何变化,其仍旧是同一个实体。唯一性由唯一的身份标识来决定。可变性也正反映了实体本身的状态和行为。
实体=唯一身份标识+可变性[状态+行为]
当你只关心某个对象的属性时,该对象便可作为一个值对象。我们需要将值对象看成不变对象,不要给他任何身份标识,还应该尽量避免像实体对象一样的复杂性。
值对象=将一个值用对象的方式进行表述,来表达一个具体的固定不变的概念。
聚合是领域对象的显式分组,旨在支持领域模型的行为和不变性,同时充当一致性和事务性边界。
我们把一些关联性极强、生命周期一致的实体、值对象放到一个聚合里。