This commit is contained in:
by931
2022-09-06 22:30:37 +08:00
parent 66970f3e38
commit 3d6528675a
796 changed files with 3382 additions and 3382 deletions

View File

@@ -538,7 +538,7 @@ function hide_canvas() {
<p><img src="assets/da59ee30-acf2-11e8-9c45-adc0fa12a28f" alt="img" /></p>
<h4>领域驱动设计的经典分层架构</h4>
<p>领域驱动设计在经典三层架构的基础上做了进一步改良在用户界面层与业务逻辑层之间引入了新的一层即应用层Application Layer。同时一些层次的命名也发生了变化将业务逻辑层更名为领域层自然是题中应有之义而将数据访问层更名为基础设施层Infrastructure Layer则突破了之前数据库管理系统的限制扩大了这个负责封装技术复杂度的基础层次的内涵。下图为 Eric Evans 在其经典著作《领域驱动设计》中的分层架构:</p>
<p><img src="assets/f942d550-acf2-11e8-afe5-6ba901a27e1b" alt="enter image description here" /></p>
<p><img src="assets/f942d550-acf2-11e8-afe5-6ba901a27e1b" alt="png" /></p>
<p>该书对各层的职责作了简单的描述:</p>
<table>
<thead>
@@ -581,7 +581,7 @@ function hide_canvas() {
<p>我们之所以要以水平方式对整个系统进行分层,是我们下意识地确定了一个认知规则:<strong>机器为本,用户至上</strong>,机器是运行系统的基础,而我们打造的系统却是为用户提供服务的。分层架构中的层次越往上,其抽象层次就越面向业务、面向用户;分层架构中的层次越往下,其抽象层次就变得越通用、面向设备。为什么经典分层架构为三层架构?正是源于这样的认知规则:其上,面向用户的体验与交互;居中,面向应用与业务逻辑;其下,面对各种外部资源与设备。在进行分层架构设计时,我们完全可以基于这个经典的三层架构,沿着水平方向进一步切分属于不同抽象层次的关注点。因此,<strong>分层的第一个依据是基于关注点为不同的调用目的划分层次</strong>。以领域驱动设计的四层架构为例之所以引入应用层Application Layer就是为了给调用者提供完整的业务用例。</p>
<p><strong>分层的第二个依据是面对变化</strong>。分层时应针对不同的变化原因确定层次的边界,严禁层次之间互相干扰,或者至少把变化对各层带来的影响降到最低。例如,数据库结构的修改自然会影响到基础设施层的数据模型以及领域层的领域模型,但当我们仅需要修改基础设施层中数据库访问的实现逻辑时,就不应该影响到领域层了。<strong>层与层之间的关系应该是正交的</strong>,所谓“正交”,并非二者之间没有关系,而是垂直相交的两条直线,唯一相关的依赖点是这两条直线的相交点,即两层之间的协作点,正交的两条直线,无论哪条直线进行延伸,都不会对另一条直线产生任何影响(指直线的投影);如果非正交,即“斜交”,当一条直线延伸时,它总是会投影到另一条直线,这就意味着另一条直线会受到它变化的影响。</p>
<p>在进行分层时,我们还应该<strong>保证同一层的组件处于同一个抽象层次</strong>。这是分层架构的设计原则,它借鉴了 Kent Beck 在 Smalltalk Best Practice Patterns 一书提出的“组合方法”模式该模式要求一个方法中的所有操作处于相同的抽象层这就是所谓的“单一抽象层次原则SLAP这一原则可以运用到分层架构中。例如在一个基于元数据的多租户报表系统中我们特别定义了一个引擎层Engine Layer这是一个隐喻相当于为报表系统提供报表、实体与数据的驱动引擎。引擎层之下是基础设施层提供了多租户、数据库访问与元数据解析与管理等功能。在引擎层之上是一个控制层通过该控制层的组件可以将引擎层的各个组件组合起来分层架构的顶端是面向用户的用户展现层如下图所示</p>
<p><img src="assets/19351620-acf3-11e8-afe5-6ba901a27e1b" alt="enter image description here" /></p>
<p><img src="assets/19351620-acf3-11e8-afe5-6ba901a27e1b" alt="png" /></p>
<h4>层与层之间的协作</h4>
<p>在我们固有的认识中,分层架构的依赖都是自顶向下传递的,这也符合大多数人对分层的认知模型。从抽象层次来看,层次越处于下端,就会变得越通用越公共,与具体的业务隔离得越远。出于重用的考虑,这些通用和公共的功能往往会被单独剥离出来形成平台或框架,在系统边界内的低层,除了面向高层提供足够的实现外,就都成了平台或框架的调用者。换言之,越是通用的层,越有可能与外部平台或框架形成强依赖。若依赖的传递方向仍然采用自顶向下,就会导致系统的业务对象也随之依赖于外部平台或框架。</p>
<p>依赖倒置原则Dependency Inversion PrincipleDIP提出了对这种自顶向下依赖的挑战它要求“高层模块不应该依赖于低层模块二者都应该依赖于抽象”这个原则正本清源给了我们严重警告——谁规定在分层架构中依赖就一定要沿着自顶向下的方向传递我们常常理解依赖是因为被依赖方需要为依赖方调用方提供功能支撑这是从功能重用的角度来考虑的。但我们不能忽略变化对系统产生的影响与建造房屋一样我们自然希望分层的模块“构建”在稳定的模块之上谁更稳定抽象更稳定。因此依赖倒置原则隐含的本质是<strong>我们要依赖不变或稳定的元素(类、模块或层)</strong>,也就是该原则的第二句话:<strong>抽象不应该依赖于细节,细节应该依赖于抽象</strong></p>