mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-11-17 22:53:43 +08:00
fix img
This commit is contained in:
@@ -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 Principle,DIP)提出了对这种自顶向下依赖的挑战,它要求“高层模块不应该依赖于低层模块,二者都应该依赖于抽象”,这个原则正本清源,给了我们严重警告——谁规定在分层架构中,依赖就一定要沿着自顶向下的方向传递?我们常常理解依赖,是因为被依赖方需要为依赖方(调用方)提供功能支撑,这是从功能重用的角度来考虑的。但我们不能忽略变化对系统产生的影响!与建造房屋一样,我们自然希望分层的模块“构建”在稳定的模块之上,谁更稳定?抽象更稳定。因此,依赖倒置原则隐含的本质是:<strong>我们要依赖不变或稳定的元素(类、模块或层)</strong>,也就是该原则的第二句话:<strong>抽象不应该依赖于细节,细节应该依赖于抽象</strong>。</p>
|
||||
|
||||
Reference in New Issue
Block a user