领域驱动设计--战术模式简介

战术模式包含若干构造块模式,以便可以构建有效的领域模型。并发

战术模式严重依赖于领域模型和通用语言,经过技术模式将领域模型和通用语言中的概念映射到代码实现中。随着模型的进化,代码实现也会进行重构,以更好的体现模型概念。 固然,从技术重构角度也会发现一些隐含领域知识(概念),这些新的发现也会对领域模型产生影响。框架

战术模式和通用语言同样,都工做在特定限界上下文内,其应用边界受限界上下文的保护。函数

1 战术模式

战术模式的做用是管理复杂性并确保领域模型中行为的清晰明确。可使用这些模式来捕获和传递领域中的概念、关系、规则。设计

每一个构造块模式都具备单一职责:cdn

  1. 表明领域中的概念。如实体、值对象、领域服务、领域事件、模块等;
  2. 用于管理对象的生命周期。如聚合、工厂、仓库等;
  3. 用于集成或跟踪。领域事件、事件溯源等。

战术模式 领域模型构造块

1.1 领域建模模式

他们表述实现与模型间的关系,将分析模型绑定到代码实现模型。主要用于在代码中表述模型元素的模式。对象

1.1.1 实体

实体表述的是领域中的概念,它是由身份而不是属性来定义的。blog

实体的身份标识在生命周期中保持不变,但其属性会发生变化。实体以身份标识做为惟一凭证,沿着时间轴,记录了实体全部变动事件。接口

实体的一个实例是产品,一旦产品被生成好,其惟一身份就不会发生变化,可是其描述信息、价格等能够被屡次修改。生命周期

实体

1.1.2 值对象

值对象表明仅经过数据区分的领域元素和概念。用做模型中元素的描述,它不具备惟一标识。事件

值对象不须要惟一标识,是由于它老是与另外一个对象相关联,是在一个特定上下文中被解析的。一般,其生命周期会依附于它的关联对象(在这里,主要是实体对象)。

值对象会当作不变对象来设计,在完成建立后,其状态就不能改变了。

值对象比较好的例子就是现金,你无需关系货币的身份,只关心它的价值。若是有人用一张五美圆钞票交换你的五张一美圆钞票,也不会改变五美圆自己。

值对象

1.1.3 领域服务

在模型中,领域服务封装了不能天然建模为值对象和实体的逻辑、流程和概念。

它自己不具备身份和状态。它的职责是使用实体和值对象编排业务逻辑。

领域服务的一个好例子是运输成本计算器,只要给出一组拖运货物和重量,它就能计算运输成本。

1.1.4 模块

模块主要用于组织和封装相关概念(实体、值对象、领域服务、领域事件等),这样能够简化对较大模型的理解。

应用模块能够在领域模型中促成低耦合和搞内聚的设计。

模块做用于单个领域,用于分解模型规模。子域用于限定领域模型适用范围(有界上下文)。

1.2 对象生命周期模式

相对来讲,以前提到的模式重点在于表达领域概念。而对象生命周期模式,有点侧重于技术,用于表示领域对象的建立和持久化。

1.2.1 聚合

实体和值对象会相互协做,造成复杂的关联关系。咱们须要在知足不变条件的前提下,将其拆分为一个个概念上的总体。

一般,面对复杂的对象关系,在执行领域对象操做时,难以保证一致性和并发性。

领域驱动设计由聚合模式来确保操做的一致性和事务的并发边界。大模型会经过不变性条件来划分,并组成概念化总体的实体和对象组,这个概念化总体即是聚合。

聚合根之间的关系应该经过保持对另外一个聚合根 ID 的引用,而非对对象自己的引用来实现。这一原则有助于保持聚合之间的边界并避免加载没必要要的对象。

不变性,是在领域模型中强制实现一致性的规则。不管什么时候对实体或聚合进行变动都要应用该业务规则。

聚合外部的对象只能引用另外一个聚合的聚合根,聚合中对象的任何变动都须要经过聚合根来完成。聚合根封装聚合数据并公开行为以对其进行修改。

聚合

1.2.2 工厂

若是实体或值对象的建立过程很是复杂,能够将其委托给工厂。工厂会确保在领域对象使用以前就知足全部的不变条件。

若是领域对象很简单而且不具备特殊的不变条件,可使用构造函数代替工厂。当从持久化存储中重建领域对象时,也可使用工厂。

工厂

1.2.3 仓库

仓库主要用于持久化一个聚合。将聚合做为原子单元进行处理,所以,仓库操做的最小单元就是聚合,每一个聚合会对应一个仓库。

仓库

仓库是用来检索和存储聚合的机制,是对基础框架的一种抽象。

1.3 其余模式

1.3.1 领域事件

领域事件表示问题空间中发生了一些业务人员关心的事情。主要用于表示领域概念。

使用领域事件主要有如下两种场景:

  1. 记录模型的变动历史;
  2. 做为跨聚合通讯方式。
1.3.2 事件溯源

传统的仅快照式持久化的一个替代项即是事件溯源。做为实体状态存储的替代,能够存储引起该状态的系列事件。

存储全部的事件会提升业务的分析能力,不只能够得知实体当前状态,还能够得知过去任意时点的状态。

事件溯源

1.4 总结

  1. 实体
    • 由惟一标识符定义
    • 标识符在整个生命周期保存不变
    • 基于标识符进行相等性检查
    • 经过方法对属性进行更新
  2. 值对象
    • 描述问题域中的概念和特征
    • 不具有身份
    • 不变对象
  3. 领域服务
    • 处理没法放置在实体或值对象中的领域逻辑
    • 无惟一标识
    • 无状态服务
  4. 模块
    • 分解、组织和提升领域模型的可读性
    • 命名空间,下降耦合,提供模型高内聚性
    • 定义领域对象组间的边界
    • 封装比较独立的概念,是比聚合、实体等更高层次的抽象
  5. 聚合
    • 将大对象图分解成小的领域对象群,下降技术实现的复杂性
    • 表示领域概念,不只仅是领域对象集合
    • 肯定领域一致性边界,确保领域的可靠性
    • 控制并发边界
  6. 工厂
    • 将对象的使用和构造分离
    • 封装复杂实体和值对象的建立逻辑
    • 保障复杂实体和值对象的业务完整性
  7. 仓库
    • 是聚合根在内存中的集合接口
    • 提供聚合根的检索和持久化需求
    • 将领域层与基础实施层解耦
    • 一般不用于报告需求
  8. 领域事件
    • 业务人员所关心的事件,是通用语言的一部分
    • 记录聚合根的全部变动
    • 处理跨聚合的通讯需求
  9. 事件溯源
    • 使用历史事件记录替换快照存储
    • 提供对历史状态的查询
相关文章
相关标签/搜索