《实现领域驱动设计》摘抄

我记得当时第一次看这本书的时候是在去西安旅行的飞机上和等待途中,当时我记得一下子就被这本书的语言个风格所吸引,但是当时只是一边旅行一边看书,所以还是没有完全看完这本书。今天我又再次拿起来准备阅读的,想想前些天阅读的,《深入立即Java虚拟机》,完全是不同的感受,那本书和Java编程思想有的一拼,全是 纯文字的,看起来相当地吃力,有很多的概念也是完全不好理解和记忆的,然而我也是不喜欢记忆的一个人,所以我还是有足够的信心可以好好阅读和吸收这本书的精华的。我也顺便把这本书的原版英文书打开了看了一下,发现有2点。第一滕云的翻译能力和对语言的理解能力真得很令我欣赏。第2点就是我阅读英文书的能力还是有待提高,理解使用英语写的文字是一个值得我坚持的习惯,同时我也是需要对比着学习别人的翻译能力。

第一章 DDD入门,我简单的总结一下,也可以说是记录一下经典的话。(3/17)

  • 领域驱动设计(DDD)作为 软件开发方法,它可以帮助我们设计高质量的软件模型。高质量软件模型至少可以提现在可测试、可伸缩、组织良好。
  • DDD首先并不是关于技术的,而是关于讨论、聆听、理解、发现和业务价值的,这些都是为了将知识集中起来。
  • 开发过程中,最大的鸿沟之一便存在于领域专家和开发者之间。通常来说,领域专家将关注点放在交付业务价值上,而开发者则将注意力放在技术实现上。DDD可以帮助团队成功地交付真正的业务价值。
  • 通用语言和界限上下文同时构成了DDD的两大支柱,并且它们是相辅相成的。
  • 通用语言是团队共享的、会随着时间推移而不断演化改变的。团队交流和代码是对通用语言的持续表达。
  • DDD强调将精力花在对业务最有价值的东西上。
  • DDD并不是画模型图,而是将领域专家的思维模型转化成有用的业务模型。DDD不是创建一个真实世界的模型,而是模仿现实。
  • 使用DDD最大的挑战之一便是:我们需要花费大量的时间和精力来思考业务领域,研究概念和术语,并且和领域专家交流,以发现、捕捉和改进通用语言。
  • 我们希望对对象行为的命名能够传达准确的业务含义,也即反映通用语言。
  • 使用DDD开发可以结合测试驱动和敏捷开发的方法。
  • 最后一点,实现DDD需要团队同心协力。

第二章 领域、子域和界限上下文.我也简单总结一下。(3/18)

  • 领域(Domain)即是一个组织所有的事情以及其中所包含的一切。每个组织都有它自己的业务范围和做事方式。这个业务范围以及其中所进行的活动便是领域。
  • 领域既可以表示整个业务系统,也可以表示其中的某个核心域或者支撑子域。
  • 在DDD中,一个领域被分为若干个子域,领域模型在界限上下文中完成开发。事实上,在开发一个领域模型时,我们关注的通常只是这个业务系统的某个方面。
  • 通过使用DDD战略设计工具,我们可以按照实际功能将这些交织的模型划分成逻辑上相互分离的子域,从而在一定程度上减少系统的复杂性。
  • 子域并不是一定要做得很大,并且包含很多功能。有时,子域可以简单到只包含一套算法。
  • 如果这样的界限上下文对应着业务的某些重要方面,但却不是核心,那么它便是一个支撑子域。创建支撑子域的原因在于它们专注于业务的某个方面,否者,如果一个子域被用于整个业务系统,那么这个子域便是通用子域。
  • 领域中还同时存在问题空间和解决方案空间。在问题空间中,我们思考的是业务所面临的挑战,而在解决方案空间中,我们思考如何实现软件以解决这些业务挑战。
  • 解决方案空间在很大程度上受到现有系统和技术的影响。
  • 界限上下文是一个显式的边界,领域模型便存在这个边界之内。限界上下文主要是一个语义上的边界,我们应该通过这一点来衡量对一个限界上下文的使用正确与否。
  • 界限上下文主要用来封装通用语言和领域对象,但同时它也包含了那些为领域模型提供交互手段和辅助功能的内容。
  • 使用隔离内核的时机是当你有一个非常重要的界限上下文,但是其中模型的关键部分却被大量的起辅助作用的功能所掩盖了。
  • 采用额外的战略模式,可以将可重用的模型分离到单独的界限上下文中,并在不同的界限上下文之间进行合适的集成。

第三章 上下文映射图。简单总结一下。(3/18)

  • 项目的上下文映射图可以通过两种方式表示,一种是一个简单的框图,另一种就是通过界限上下文集成的源代码实现来表示。
  • 上下文映射图主要帮助我们从解决方案空间的角度看待问题。
  • 上下文映射图表现的是项目当前的状态,如果项目在将来发生变化,上下文映射图可以做相应的更新。
  • 界限上下文之间的关系有:合作关系、共享内核,客户方-供应方开发、遵奉者、防腐层、开放主机服务、发布语言、另谋他路、大泥球。
  • 在迭代过程中,思考和讨论可以帮助我们改进上下文映射图,比如对集成点进行改进,这将有助于描述界限上下文之间的关系。
  • 我们应该将有助于团队交流的高层次元素加入上下文映射图中,而不是龙凤冗繁的细节,保持简单性和敏捷性,这样创建的上下文映射图将对项目起推动作用,而不是阻碍作用。

第四章 架构。(3/21)

  • DDD的一大好处便是它不需要特定的架构。
  • 分层架构的一个重要原则是:每层只能与位于其下方的层发生耦合。
  • 依赖倒置原则:高层模块不应该依赖于低层模块,两者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。
  • 六边形架构具有对称性特征。
  • 面向服务架构精神所在:业务价值高于技术策略,战略目标高于项目利益。
  • Rest作为一种架构风格,它将不同架构实现所共有的东西抽象出来,使得我们在谈及架构时不至于陷入技术细节中。
  • DDD和RESTful HTTP结合起来的两种方法:(1)为系统接口层单独创建一个界限上下文,再在此上下文中通过适当的策略访问实际的核心模型。(2)用于需要使用标准媒体类型的时候。如果某种媒体类型并不用于支持单个系统接口,而是用于一组相似的客户端-服务器交互场景,此时我们可以创建一个领域模型来处理每一种媒体类型。
  • CQRS:一个方法要么是执行某种动作的命令,要么是返回数据的查询,而不能两者皆是。CQRS旨在解决数据显示复杂性问题。
  • EDA事件驱动架构是一种用于处理事件的生成、发现和处理等任务的软件架构。
  • 在一个长时处理过程(Saga)中,可能存在许多彼此分离的业务处理过程同时运行。采用长时处理过程可以感受到分布式和并行处理带来的优雅,也有助于开发高可伸缩性、高可用性的业务系统。
  • 事件源:对于某个聚合上的每次命令操作,都有至少一个领域事件发布出去。该领域事件描述了操作的执行结果。
  • 数据网织的一个好处是它对领域模型提供了自然的支持,几乎消除了所有的阻抗失配。
  • 数据网织可以很好地支持事件驱动架构风格,因为它能确保对事件的投递。它还可以在所有复制缓存范围内完成分布式处理,然后将处理结果聚合到一起发给客户端。

第五章 实体。(3/22)

  • 当我们需要考虑一个对象的个性特征,或者需要区分不同的对象时,我们引入实体这个领域概念。一个实体是一个唯一的东西,并且可以在相当长的一段时间内持续地变化。
  • 唯一的身份标识和可变性特征将实体对象和值对象区分开来。
  • 一共有4中方式生成唯一标识:用户提供、应用程序生成、持久化机制生成、另一个界限上下文提供。
  • 实体唯一标识的生成既可以发生在对象创建的时候,也可以发生在持久化对象的时候。
  • 委派标识通常是为了满足ORM机制所产生的。
  • 有时一个实体维护了一个或者多个不变条件。不变条件即是在整个实体生命周期中都必须保持事务一致性的一种状态。
  • 验证的主要目的在于检查模型的正确性,检查的对象可以是某个属性,也可以是整个对象,甚至是多个对象的组合。
  • 跟踪变化最实用的方法是领域事件和事件存储。

第六章 值对象。(3/26)

  • 我们应该尽量使用值对象来建模而不是实体,即便一个领域概念必须建模成实体,在设计时也应该更偏向将其作为值对象容器,而不是实体容器。
  • 值对象特征:度量或描述、不变性、概念整体、可替换性、值对象相等性、无副作用行为。
  • 值对象还可以实现最小化集成,即可以最小化下游模型中用于管理职责的属性数目,使用值对象可以使我们做更少的职责假设。
  • 用值对象表示标准类型。标准类型是用于表示事物类型的描述对象。系统中既有表示事物的实体和描述实体的值对象,同时还存在标准类型来区分不同的类型。
  • Java中枚举是实现标准类型的一种简单方法。枚举提供了一组数量有限的值对象,它是非常轻量的,而且无副作用。
  • 在设计领域模型时,从客户端的角度思考有助于捕获关键的领域概念。否则,我们便是在从自己的角度设计模型,而不是从业务的角度。
  • 持久化值对象是通过一种非范式的方式完成的,即所有的属性和实体对象都保存在相同的数据库表中。这样可以优化对值对象的保存和读取,并且可以防止持久化逻辑泄漏到模型中。
  • ORM可以将单个值对象持久化到表中的列,也可以将多个值对象序列化到单个列中。使用数据库实体保存多个值对象,还可以使用联合表保存多个值对象。
  • 持久化Java枚举的一种简单方式是保存枚举所对应的文本展现。