领域驱动设计学习笔记

liuxingqi bio photo By liuxingqi Comment

领域驱动设计——软件核心复杂性应对之道

  1. 通过将文档减至最少,并且主要用它来补充代码和口头交流,可以避免文档和项目脱节。

  2. 任何参与建模的技术人员,不管在项目中的职责是什么,都必须花时间了解代码。任何负责修改代码的人则必须学会用代码来表达 模型。每一个开发人员都必须不同程度地参与模型讨论并且与领域专家保持密切联系。参与不同工作的人都必须有意识地通过通用语言 与接触代码的人及时交换关于模型的想法。

  3. 一个对象是用来表示某种具有连续性和标识的事物呢,还是用于描述某种状态的属性呢?这是 Entity 和 Value Object 之间 最根本的区别。

  4. 主要由标识定义的对象被称作 Entity。Entity 可以是任何事物,只要满足两个条件即可,一是它在整个生命周期中具有连续性, 二是它的区别并不是由那些对用户非常重要的属性决定的。

    Entiry 又称为 Reference Object

  5. 用于描述领域的某个方面而本身没有概念标识的对象称为 Value Object(值对象)。值对象被实例化之后用来表示一些设计元素,对于 这些设计元素,我们关心它们是什么,而不关心它们是谁。

  • 值对象可以是其他对象的集合
  • 值对象可以引用 Entity
  • 值对象经常作为参数在对象之间传递消息。它们常常是临时对象,再一次操作中被创建,然后丢弃
  • 值对象可以用作 Entity 或其他 value 的属性
  • 值对象应该是不可变的,不要为它分配任何标识,而且不要把它设计成 Entity 那么复杂
  1. 当领域中某个重要的过程或转换操作不是 Entity 或 Value Object 的自然职责时,应该在模型中添加一个作为独立接口的操作, 并将其声明为 Service。定义接口时要使用模型语言,并确保操作名称是通用语言中的术语。此外,应该使 Service 是无状态的。

    无状态是指任何客户都可以使用某个 service 的任何实例,而不必关心该实例的历史状态。

  2. Service 是应客户端请求来完成某事,当对软件中的某项无状态的活动进行建模时,就可以将该活动作为一项 Service。

  3. 应该将 Entity 和 Value Object 分门别类的聚集到 Aggregate(聚合)中,并定义每个聚合的边界。在每个聚合中,选择一个 Entity 作为根,并通过根来控制对边界内其他对象的所有访问。只允许外部对象保持对根的引用。对内部成员的临时引用可以被传递出去,但仅在一次操作中有效。由于根控制访问,因此不能绕过它来修改内部对象。这种设计有利于确保聚合中的对象满足所有固定规则,也可以确保在任何状态变化时聚合作为一个整体满足固定规则。

  4. 应该将创建复杂对象的实例和聚合的职责转移给单独的对象,这个对象本身可能没有承担领域模型中的职责,但它仍是领域设计的一部分。 提供一个封装所有复杂装配操作的接口,而且这个接口不需要客户引用要被实例化的对象的具体类,在创建聚合是要把它作为一个整体,并确保 它满足固定的规则。

  5. 除了通过根来遍历查找对象这种方法外,禁止用其他方法对聚合内部的任何对象进行访问。

  6. 在所有持久化对象中,有一小部分必须通过基于对象属性的搜索来全局访问。当很难通过遍历方式来访问某些聚合的根的时候,就需要使用这种访问 方式。它们通常是 Entity,有时是具有复杂内部结构的 Value Object,还可能是枚举 Value。而其他对象则不宜使用这种访问方式,因为这会 混淆它们之间的重要区别。随意的数据库查询会破坏领域对象的封装和聚合。技术基础设施和数据库访问机制的暴露会增加客户的复杂度,并妨碍模型驱动的设计。

  7. 为每种需要全局访问的对象类型创建一个对象,这个对象相当于该类型的所有对象在内存中的一个集合的“替身”。通过一个众所周知的全局接口来提供访问。提供 添加和删除对象的方法。用这些方法来封装在数据存储中实际插入或删除数据的操作。提供根据具体条件来挑选对象的方法,并返回属性值满足查询条件的对象或对象集合( 所返回的对象是完全实例化的),从而将实际的存储和查询技术封装起来。只为那些确实需要直接访问的聚合根提供 Repository。让客户始终聚焦于模型,从而将对象的存储 和访问操作交给 Repository 来完成。

实现领域驱动设计

  1. 从战略层面来讲,企业应该在核心域上胜人一筹。我们应该给予核心域最高的优先级、最资深的领域专家和最优秀的开发团队。 在实施 DDD 的过程中,你将主要关注于核心域。

  2. 有些相似的对象拥有不同的属性和行为,此时我们可以认为上下文边界的划分是合理的。然而,如果你在不同的界限上下文看到 了完全相同的对象,这通常意味着你的模型是错误的。

  3. 一个团队,一个界限上下文。团队中,领域专家和开发者只关注于一个界限上下文的通用语言。

comments powered by Disqus