《架构整洁之道》之整洁架构

过去几十年中,我们曾见证过一系列关于系统架构的想法被提出,列举如下:

  • 六边形架构(也称为端口与适配器架构);
  • DCI架构;
  • BCE架构。

虽然这些架构在细节上各有不同,但总体来说非常相似。它们都具有同一个设计目标:按照不同关注点对软件进行切割。也就是说,这些架构都会将软件切割成不同的层,至少有一层是只包含该软件的业务逻辑的,而用户接口、系统接口则属于其他层。

这些架构设计出来的系统,通常都具有以下特点:

  • 独立于框架:这些系统的架构并不依赖于某个功能丰富的框架之中的某个函数。框架可以被当成工具来使用,但不需要让系统来适应框架。
  • 可被测试:这些系统的业务逻辑可以脱离UI、数据库、Web服务以及其他的外部元素来进行测试。
  • 独立于UI:这些系统的UI变更起来很容易,不需要修改其他的系统部分。
  • 独立于数据库:我们可以轻易将这些系统使用的Oracle、SQL Server替换成Mongo、BigTable、CouchDB之类的数据库。因为业务逻辑与数据库之间已完成了解耦。
  • 独立于任何外部机构:这些系统的业务逻辑并不需要知道任何其他外部接口的存在。

整洁架构:

  • 最外层:Web、用户界面、外部接口、数据库、设备、框架与驱动程序;
  • 次外层:网关、控制器、展示器;
  • 内层:用例、应用级业务逻辑、接口适配器;
  • 最内层:业务实体、系统级业务逻辑。

一、依赖关系规则

源码中的依赖关系必须只指向同心圆的内层,即由低层机制指向高层策略。
换句话说,就是任何属于内层圆中的代码都不应该牵涉外层圆中的代码,尤其是内层圆中的代码不应该引用外层圆中代码所声明的名字,包括函数、类、变量以及一切其他由命名的软件实体。

二、业务实体

业务实体这一层封装的是整个系统的关键业务逻辑,一个业务实体既可以是一个带有方法的对象,也可以是一组数据结构和函数的集合。无论如何,只要它能被系统中的其他不同应用复用就可以。

三、用例

软件的用例层中通常包含的是特定应用场景下的业务逻辑,这里面封装并实现了整个系统的所有用例。这些用例引导了数据在业务实体之间的流入/流出,并指挥着业务实体利用其中的关键业务逻辑来实现用例的设计目标。

四、接口适配器

软件的接口适配器层中通常是一组数据转换器,它们负责将数据从对用例和业务实体而言最方便操作的格式。

五、框架与驱动程序

框架与驱动程序层中包含了所有的实现细节。Web是一个实现细节,数据库也是一个实现细节。我们将这些细节放在最外层,这样它们就很难影响到其他层了。

六、只有四层吗

并没有某个规则约定一个系统的架构有且只能有四层。然而,这其中的依赖关系原则是不变的。也就是说,源码层面的依赖关系一定要指向同心圆的内侧。层次越往内,其抽象和策略的层次越高,同时软件的抽象程度就越高,其包含的高层策略就越多。最内层的圆中包含的是最通用、最高层的策略,最外层的圆包含的是最具体的实现细节。

七、跨越边界

利用动态多态技术,我们将源码中的依赖关系与控制流的方向进行反转。不管控制流原本的方向如何,我们都可以让它遵守架构的依赖关系规则。

八、哪些数据会跨越边界

一般来说,会跨越边界的数据在数据结构上都是很简单的。如果可以的话,我们会尽量采用一些基本的结构体或简单的可传输数据对象。或者直接通过函数调用的参数来传递数据。另外,我们也可以将数据放入哈希表,或整合成某种对象。这里最重要的是这个跨边界传输的对象应该有一个独立、简单的数据结构。总之,不要投机取巧地直接传递业务实体或数据库记录对象。同时,这些传递的数据结构中也不应该存在违反依赖规则的依赖关系。

文章目录
  1. 一、依赖关系规则
  2. 二、业务实体
  3. 三、用例
  4. 四、接口适配器
  5. 五、框架与驱动程序
  6. 六、只有四层吗
  7. 七、跨越边界
  8. 八、哪些数据会跨越边界