本书是Eric Evans对他自己写的《领域驱动设计-软件核心复杂性应对之道》的一本字典式的参考书,可用于快速查找《领域驱动设计》中的诸多概念及其简明解释。
其它本系列其它文章地址:
[译文]Domain Driven Design Reference(一)—— 前言
[译文]Domain Driven Design Reference(二)—— 让模型起作用
[译文]Domain Driven Design Reference(三)—— 模型驱动设计的构建模块
[译文]Domain Driven Design Reference(四)—— 柔性设计
[译文]Domain Driven Design Reference(五)—— 为战略设计的上下文映射
[译文]Domain Driven Design Reference(六)—— 提炼战略设计
你如何专注于你的核心问题,并避免陷入一大堆细枝末节?
提炼是是一种分离混合物成分的过程,以提取出一种使其更有价值和有用的形式。模型是知识的提炼。随着每一次重构的深入,我们抽象出领域知识和优先级的一些关键方面。现在,回过头来看战略视角,本章将探讨如何区分模型的涉猎范围并提炼整个领域模型。
核心领域
在一个大型系统中,有太多的合作组件,一切都很复杂,但都是成功的必要条件,所以领域模型的本质,真正的商业资产,可能会被掩盖和忽略。
残酷的现实是,并非所有设计的部分都要同样的精炼。优先事项必须确定。为了使领域模型成为一种资产,该模型的关键核心必须是整洁且充分利用来创建应用程序功能。但是缺乏丰富经验的开发者倾向于对技术基础设施或者可清晰定义的领域问题感兴趣,这些问题可以在没有专门领域知识的情况下被理解。
因此:
归纳模型。定义一个核心域,并提供一种可以很容易区分支持模型和代码的方法。让最有价值和最专业的概念显露出来。
将顶尖人才应用到核心领域,并据此招聘。在核心中花费精力寻找一个深层的模型,并开发一个柔性设计来实现系统的远景。
通过如何支持提炼出来的核心来证明对其他任何部分的投资是合理的。
通用子域
模型的某些部分增加了复杂性,而没有捕获或传播专业知识。任何无关紧要的东西都会使核心领域更难识别和理解。这个模型符合所有人都知道或者是属于专业的一般原则,这些原则不是你的主要关注点,而是发挥辅助作用。然而,这些其他的元素对于系统的功能和模型的完整表达都是必不可少的。
因此:
识别不是你的项目动机的内聚子域。提取出这些子域的通用模型,并将它们放在单独的模块中。不要留下你的特点。
一旦它们被分离,将它们的后续开发优先级置于核心领域之下,并避免你的核心去做这些任务(因为这些核心开发将从他们那里获得很少的领域知识)。还要考虑这些通用子域的现成解决方案或已发布的模型。
领域愿景宣言
在项目开始时,模型通常是不存在的,但是关注其发展的需求已经存在。在开发的后期阶段,需要对系统的价值进行解释,而不需要对模型进行深入研究。此外,领域模型的关键方面可能跨越多个限界上下文,但是根据定义,这些不同的模型不能被构造来显示它们的共同焦点。
因此:
写一个关于核心领域的简短描述(大概一页)以及它将带来的价值,即“价值主张”。忽略那些不区分该领域模型和其它东西的方面。显示领域模型如何服务和平衡多种利益。保持它的精简。尽早写下此声明,并在获得新见解时对其进行修改。
突出核心
领域愿景宣言以广义的术语来标识核心领域,但是它将特定的核心模型元素的识别留给了个体的解释。除非团队中的沟通水平非常高,否则单凭愿景宣言没有多大影响。
即使团队成员大致知道什么是核心领域,但不同的人不会挑出相同的元素,即使是同一个人,在不同的时间点做出的选择也不一定是一致的。不断过滤模型以识别关键部分的脑力劳动更好地将注意力集中在设计思维上,并且需要对模型有全面的认识。必须使核心域更容易看到。
对代码进行重大的重构是识别核心领域的理想方式,但它们在短期内并不总是实用的。事实上,如果没有团队所缺乏的观点,这种重大的代码重构就很难进行。
因此(作为突出核心的一种形式):
编写一个非常简短的文档(3到7个简单页面),描述核心领域和核心元素之间的主要交互。
和/或(作为突出核心的另一种形式):
在模型的主存储库中标记核心领域的元素,而不是特别地试图阐明其角色。让开发人员轻松了解核心的内外内容。
如果浓缩文件概括了核心领域的要点,那么它就可以作为一个实际的指标,说明模型变更的重要性。当模型或代码变更影响到浓缩文档时,需要与其他团队成员协商。当更改完成时,需要立即通知所有团队成员,并传播新版本的文档。除核心外的变更或未包含在浓缩文档中的细节,可以不经协商或通知的情况下进行而集成,并且其他成员在其工作过程中也会遇到。然后开发人员拥有绝大多数敏捷过程所建议的自主权。
尽管有愿景宣言和突出的核心信息和指南的存在,但是它们实际上并没有修改模型或代码本身。划分通用子域将从物理上去除一些分散注意力的元素。接下来,我们将研究其它方式来结构性地更改模型和设计本身,以使核心领域更易理解和管理。。。
内聚机制
开始膨胀设计使得计算有时会达到一个复杂程序。概念性的"做什么"被机械的"如何做"所淹没。提供解决问题算法的大量方法模糊了表达问题的方法。
因此:
将概念上的内聚机制分离到一个单独的轻量级框架。特别注意形式主义或有良好文档的算法类别。用意图揭示接口来公开框架的功能。现在,领域中的其他元素就可以只专注与如何表达问题(做什么)了,而把解决方案的复杂细节(如何做)转移给了框架。
分解通用子域会减少混乱,而内聚机制有助于封装复杂的操作。这就留下了一个更专注的模型,减少了对用户进行活动的方式没有特别价值的这类干扰。但是,你不可能在没有核心的领域模型中找到好的结果。分离的核心是采取直接的方式来结构化地标记出核心领域。。。
隔离核心
模型中的元素可能部分服务于核心领域,并且部分扮演辅助角色。核心元素可能与通用元素紧密耦合。核心的概念性内聚力可能不强或缺失。所有这些混乱和复杂关系扼杀了核心。设计师不能清楚地看到最重要的关系,导致设计薄弱。
因此:
对模型进行重构,把核心概念从支持性元素(包括定义得不清楚的那些元素)中分离出来,并增强核心的内聚性,同时减少它与其他代码的耦合。把所有通用元素或支持性元素提取到其他对象中,并把这些对象放到其他的包中,即使这会把一些紧密耦合的元素分开。
抽象核心
即使是核心领域模型通常也有很多细节,因此沟通大局面可能是困难的。当单独模块中的子域之间存在很多交互时,要么在模块之间创建许多引用,要么就会破坏分区的大部分价值,否则交互将不得不间接地进行,这使得模型变得模糊。
因此:
确定模型中最基本的区分概念,并将它们分为不同的类,抽象类或接口。设计这个抽象模型,以表达大部分重要组件之间的交互。将这个抽象的整体模型放在它自己的模块中,而专门的、具体的实现类留在由子域定义的它们自己的模块中。
作者:Zachary(个人微信号:Zachary-ZF)
微信公众号(首发):跨界架构师。<-- 点击查阅近期热门文章
定期发表原创内容:架构设计丨分布式系统丨产品丨运营丨一些深度思考。
扫码加入小圈子👇
网友评论