DDD领域驱动 - 设计领域(一)


概念

关键词:战略设计、战术设计、领域驱动、数据驱动、领域模型、领域对象、值对象、聚合、聚合根、领域、子域、核心域、通用域、支撑域、领域服务、应用服务、事件风暴

什么是DDD

DDD领域驱动不是架构,而是一种架构设计方法论。

在当今以微服务为主流的环境下,很多时候我们在拆分微服务的时候,往往是根据直觉、经验对服务进行拆分,比如订单服务、用户服务、支付服务。

但这些服务只是将传统的单体架构拆分为了多个单体架构,当某一个服务的业务经过长期发展,业务越来越负责,代码越来越臃肿。

当服务中的某些核心业务性能出现瓶颈的时候,基于微服务的理念,可能需要将出现瓶颈的业务抽取为单独的服务进行水平扩展。

这时我们发现,代码和业务都过于耦合,同一个服务中的业务之间边界不清晰,拆分成本很高。如果基于整个服务进行水平扩展,对服务器的资源浪费又比较严重,这就不利于架构的演进。

上面只是我们在微服务架构中遇到的众多问题中的一种,直到DDD的出现,通过领域建模,划分领域边界,再根据这些领域边界划分微服务,很好的贯彻了“高内聚、低耦合”的思想,它能指导我们设计出清晰的领域和应用边界,帮助我们更容易的实现架构演进。

战略设计和战术设计

战略设计: 主要从业务角度出发,建立业务领域模型,划分领域边界

战术设计: 主要从技术角度出发,侧重于领域模型的技术实现,比如代码如何分层,包括聚合根、实体、值对象、领域服务、应用服务等代码逻辑的实现

设计聚合

实体和值对象

我们以电商的创建订单场景为例,简单对业务进行分析,并落实到DDD的各个概念:

  1. 采用事件风暴,根据业务行为,梳理出所有创建订单的实体值对象,比如:用户、商户、商品、订单、购物车等等
  2. 找出聚合根,判断一个实体是不是聚合根,可以分析是否符合这些要素:
    • 独立的生命周期
    • 全局唯一ID
    • 可创建和修改其它对象
    • 有专门的模块管理这个实体
  3. 根据业务单一职责和高内聚原则,找出和聚合根关联密切的所有实体和值对象,构建出1个包含聚合根(唯一)、多个实体和值对象的集合,这个集合就是聚合。这里我们可以构建出订单、用户、商户、商品、购物车四个聚合
  4. 分析聚合之间的关系,画出对象引用和依赖模型。创建订单,需要有收件人信息和收货地址,订单在创建后这两个信息不会因为用户后续更新数据而发生更新,所以将用户信息、收货地址作为订单聚合的值对象。同理,商品信息也一样,商品和商户是独立但又紧密联系的,两者结合作为订单的值对象。一个订单中可能包含多个商户的商品,多个商户的商品属于同一个订单,但是在商户端不同商户间的订单又是隔离的,所以这里有商户订单和用户订单两个对象。其中购物车和创建订单没有直接关系,创建订单成功时,会触发领域事件“更新购物车”。

上面的分析可能不合理,只是作为DDD领域分析的一个例子

重要概念

实体

领域模型中的实体以DO(领域对象)的形式存在,每个实体对象都有一个唯一的ID,它具有业务属性和业务行为。

在代码中,实体类包含属性和方法,通过这些方法实现自身的业务,实体通常采用充血模型,与这个实体相关的所有业务逻辑都在实体的方法中实现。

值对象

通过对象属性值来识别的对象,它将多个相关属性组合为一个实体。它是只读的,不可变的。

聚合

聚合就是由业务和逻辑紧密联系的实体和值对象组合而成,它来协调实体和值对象协同工作,保证它们实现共同的业务逻辑,保证数据一致性。

在DDD领域分层中聚合属于领域层,领域层包含多个聚合,共同实现核心业务逻辑。

如果业务需要同一个聚合内的两个实体共同实现,我们可以用领域服务实现。

如果业务需要两个聚合共同实现,我们可以用应用服务来组合两个聚合实现。

聚合根

聚合根也是实体,它是聚合的管理者。它拥有实体的属性和业务行为。

作为聚合的管理者,它可以协调聚合内的所有实体和值对象,按照固定的规则协同完成业务逻辑。

实体、值对象、聚合根的区别

聚合根也是实体,有全局唯一标识,生命周期属于其所属的聚合。

实体在聚合内部有唯一标识,它的生命周期归聚合根管理,数据可变。

值对象没有唯一标识,生命周期归聚合根管理,数据只读。

聚合根和聚合根之间通过ID关联。

聚合根和其内部的实体,直接对象引用。

聚合根和其内部值对象,直接对象引用。

猜你喜欢

转载自blog.csdn.net/weixin_38403680/article/details/109684061