本系列文章通过逐章回答《Fundamentals of Software Architecture》(下文简称 FOSA)一书中的课后思考题,来深入理解书中的核心概念和理论,从而提升我们的软件架构设计能力。本篇为第十章内容。

本章的课后题是:

  1. What is the difference between an open layer and a closed layer?

    开放层和封闭层有何区别?

  2. Describe the layers of isolation concept and what the benefits are of this concept.

    隔离层概念及其益处是什么?

  3. What is the architecture sinkhole anti-pattern?

    架构漏斗反模式是什么?

  4. What are some of the main architecture characteristics that would drive you to use a layered architecture?

    驱动采用分层架构风格的主要架构特性有哪些?

  5. Why isn’t testability well supported in the layered architecture style?

    分层架构风格的可测试性为何不佳?

  6. Why isn’t agility well supported in the layered architecture style?

    分层架构风格的敏捷性为何不佳?


概念

FOSA Figure 10-2. Physical topology (deployment) variants

分层架构的核心驱动力关注点分离(Separation of Concerns)。它将一个复杂的系统按照不同的职责或技术关注点,垂直地划分成若干个水平的“层(Layer)”。

每一层都有明确的职责:

  • 表现层(Presentation Layer):负责处理用户界面和交互,例如 Web 页面或 API 端点。
  • 业务逻辑层(Business Logic Layer):实现核心的业务规则和流程,是应用的心脏。
  • 持久化层(Persistence Layer):负责数据的存储和检索,与数据库交互。
  • 数据库层(Database Layer):即实际的数据库系统。

这些层之间存在一个至关重要的约束:依赖关系是单向的。通常来说,上层可以依赖下层,但下层绝对不能依赖上层。例如,表现层可以调用业务逻辑层,但业务逻辑层不应该知道任何关于表现层的具体实现细节。

封闭层 vs 开放层

封闭层(Closed Layer):当一个请求从上层向下层传递时,它必须逐层通过。

  • 优点:提供了最高程度的隔离。由于每一层都只与它的邻居交流,下层实现细节的变更对上上层的影响被完全隔离。这正是"隔离层"概念的基础。
  • 缺点:可能会引入不必要的冗余代码和性能开销。

开放层(Open Layer):这是一种更为灵活的模式,允许上层"跳过"一个或多个中间层,直接访问更下方的层。

  • 优点:当中间层对于某个特定请求没有任何业务逻辑需要添加时,开放该层可以避免编写无意义的传递(pass-through)代码,从而提高开发效率和运行效率。
  • 缺点:破坏了层与层之间的强隔离性。如果滥用开放层,会导致层级关系混乱,上层与多个下层产生耦合,削弱分层架构带来的可维护性优势。

隔离

概念及好处

隔离指的是一个层中的变更,应该被隔离在这一层以及与之直接相邻的层中,而不会向上"泄漏"到更远的层

想象一下,如果我们决定将数据库从 MySQL 迁移到 PostgreSQL。这个变化发生在最底层的数据库层和持久化层。

  • 理想情况(强隔离):由于业务逻辑层只依赖于持久化层定义的接口(例如 UserRepository),而不知道其背后是 MySQL 还是 PostgreSQL,因此业务逻辑层代码完全不需要修改。表现层就更不受影响了。变更被成功"隔离"在了持久化层内部。
  • 隔离被破坏的情况:如果持久化层的某些特定实现细节(例如特定的 SQL 方言)泄漏到了业务逻辑层,那么在迁移数据库时,业务逻辑层也必须跟着修改。这就是隔离性的失败。

这样做的好处有:

  • 极高的可维护性
  • 技术栈的独立性
  • 系统的可理解性

潜在的陷阱:架构漏斗反模式

架构漏斗反模式描述了这样一种情况:一个请求在流经多个封闭层时,其中一些中间层没有执行任何有意义的逻辑,仅仅是将请求原封不动地传递给下一层。这些"只传话、不干活"的层就成为了架构的"漏斗"或"沉洞",增加了不必要的复杂度和代码量。

可以使用二八原则,允许 20% 的 sinkhole,如果过多的 sinkhole,则说明分层架构很可能不适用于当前的业务场景。

优点

  1. 简单性(Simplicity)和低成本(Cost):分层架构模式非常成熟,广为人知,开发团队的学习成本极低。对于中小型项目、预算有限的初创公司或内部管理系统,它是一个"足够好"的、性价比极高的起点。
  2. 可维护性(Maintainability):如前所述,只要遵循了隔离层原则,系统的维护和迭代会非常清晰。对于那些业务逻辑相对稳定、变更不频繁的系统,这是一个巨大的优势。
  3. 整体可部署性(Deployability):分层架构天然倾向于构建单体应用(Monolith)。整个应用被打包成一个单元(例如一个 WAR 包或一个可执行文件)进行部署。这极大地简化了部署和运维的复杂度,尤其是在项目早期或运维能力有限的团队中。

缺点

  • 技术分区而非领域分区:分层架构是一种技术分区架构。这意味着它的组件是根据其在架构中的技术角色(如表示层、业务层、持久层),而不是根据业务领域(如客户、订单)进行分组的。这会导致任何特定的业务领域(例如“客户”领域)的逻辑都会分散在架构的所有层中。同时,当需要对特定业务领域的需求进行更改时,由于其逻辑分散在多个技术层中,开发人员必须在所有相关层中进行修改,这降低了开发的敏捷性。
  • 部署风险高:在分层架构中,即使是对少量代码的更改(例如,一个类文件中简单的三行更改),也需要重新部署整个部署单元。这种部署往往会捆绑数十个其他更改,从而显著增加了部署风险,且部署频率受到限制。
  • 测试范围大且不完整:由于整个应用程序是作为一个大型单体单元部署的,开发人员通常不会为简单的三行更改花费数小时执行完整的回归测试套件。这导致测试覆盖范围不完整,并且难以确保更改不会影响看似不相关的部分。