Logo
Section 1 / 7

促进以数据库为中心的设计

了解层如何在软件架构中促进数据库驱动的设计。

导入

促进以数据库为中心的设计

了解层如何在软件架构中促进数据库驱动的设计。

简介

你很可能在过去开发过基于分层的(Web)应用程序,甚至当前的项目也正在采用这种结构。

在计算机科学课程、教程和最佳实践中,分层思维已经被反复强调。甚至一些重要书籍中也明确提倡这一理念:例如 Mark Richards 所著的《软件架构模式》(O’Reilly,2015年)就对此进行了深入阐述。

三层结构

...
一个传统的Web应用架构包含Web层、领域层和持久化层。

上图展示了一种常见的三层架构概览,包括:

  • Web层:接收请求,并将其路由到领域层(也称“业务”层)中的服务。
  • 服务层:执行具体的业务逻辑,并调用持久化层的组件来查询或修改领域实体的当前状态。

分层是一种成熟的架构模式。如果设计得当,我们可以构建出独立于Web层和持久化层的领域逻辑。这意味着可以根据需要更换Web技术或持久化技术,而不会影响核心业务逻辑;同时也能在添加新功能时避免对已有功能造成干扰。

良好的分层架构让我们保持灵活性,能够快速应对需求变化和外部环境的变动。如果我们认同 Uncle Bob 的观点,这正是 Robert C. Martin 在《整洁架构》(Prentice Hall,2017年,第15章)中所强调的核心思想。

那么,分层架构有什么问题?

根据我的经验,传统的分层架构存在太多开放的薄弱环节,容易让不良习惯悄然渗透,导致软件随着时间推移变得越来越难以维护和修改。

接下来的课程将详细解释这些问题。

分层架构的基础

按照传统定义,分层架构的基础是数据库。Web层依赖于领域层,而领域层又依赖于持久化层,进而依赖数据库。整个系统都建立在持久化层之上。这种设计存在多个问题。

Course Image

我们不妨退一步思考:大多数应用的根本目标是什么?通常,我们试图建立一套模型,用以反映业务规则或“策略”,从而帮助用户更方便地与这些规则交互。

我们真正要建模的是行为,而非仅仅是状态。诚然,状态是任何应用的重要组成部分,但正是行为改变了状态,进而驱动了业务运转!

那么,为什么我们要把数据库(而不是领域逻辑)作为架构的基石?

Course Image

回想一下你最近实现的应用用例:你是先编写领域逻辑,还是先设计持久化层?你很可能首先考虑数据库结构如何设计,然后再在其基础上实现领域逻辑。

从传统分层架构的角度看,这符合依赖关系的自然流向。但从业务角度来看,这完全本末倒置!我们应该优先构建领域逻辑,这是最核心的部分。只有通过实现领域逻辑,才能验证我们是否正确理解了业务需求。只有确认了这一点之后,才应着手构建围绕它的持久化层和Web层。

在这种以数据库为中心的架构中,一个关键推动因素是 ORM(对象关系映射)框架的使用。需要说明的是,我本人非常喜爱这类框架,日常工作中也频繁使用 JPA(Java 持久化 API)和 Hibernate。然而,当我们将 ORM 框架与分层架构结合使用时,很容易不自觉地将业务规则与持久化细节混杂在一起。

数据库驱动的开发方式

...
在领域层中直接使用数据库实体会导致与持久化层的高度耦合。

通常情况下,如图所示,我们会将由 ORM(对象关系映射)管理的实体作为持久化层的一部分。由于分层架构允许上层访问下层,因此领域层可以访问这些实体。而一旦允许使用,它们就一定会被使用。

这导致持久化层与领域层之间形成了强耦合。我们的服务直接将持久化模型当作业务模型使用,不仅需要处理复杂的业务逻辑,还不得不关心诸如急加载与懒加载、数据库事务、缓存刷新等底层技术细节。

持久化代码几乎与领域代码融为一体,使得修改其中一部分时很难不影响另一部分。这恰恰违背了架构应有的灵活性和可扩展性目标——即保持选项开放,便于未来调整。

Course Image

在开始之前

容易走捷径