Golang 项目架构中的一点思考 2

这篇文章我自己都看不懂抄了些什么,建议别读了。直接读相关链接。DDD 靠网上的2手文章学不明白,还是买了一套书仔细读一下。等新项目做完会把这篇文章重写。

分层架构介绍

什么是分层架构

分层体系结构指的是将系统的组件分隔到不同的层中,每一层中的组件应保持内聚性,并且应大致在同一抽象级别。每一层都应与它下面的各层保持松散耦合。

分层架构是运用最为广泛的一种架构模式,几乎每个软件系统都需要通过分层 Layer 来隔离不同的关注点 Concern Point,以应对不同需求的变化,并且使得这种变化可以独立进行。分层架构模式还是隔离业务复杂度与技术复杂度的利器。

对于分层架构来说,层次越往上其抽象层次就越面向业务和用户,层次越往下其抽象层次就越面向技术和设备。

关于 高内聚低耦合

分层架构的基本原则

每层只与位于其下方的层发生耦合。

  1. Strict Layers Architecture 严格分层架构:某层只能与其直接下层耦合。
  2. Relaxed Layers Architecture 松散分层架构:允许任意上层与任意下层耦合。由于用户接口层和应用服务通常需要与基础设施打交道,许多系统都是该架构。

较低层有时也可与较高层耦合,但只限于采用观察者 Observer 模式或者调停者 Mediator 模式场景。 较低层绝不能直接访问较高层。 例如:在使用调停者模式时,较高层可能实现了较低层的接口,然后将实现对象作为参数传递到较低层。当较低层调用该实现时, 它并不知道实现出自何处。

分层的依据与原则

分层的第一个依据是基于关注点为不同的调用目的划分层次。以领域驱动设计的四层架构为例,之所以引入应用层(Application Layer),就是为了给调用者提供完整的业务用例。

分层的第二个依据是面对变化。层与层之间的关系应该是正交的。将变化对各层带来的影响降到最低。例如数据库结构的修改自然会影响到基础设施层的数据模型以及领域层的领域模型,但当我们仅需要修改基础设施层中数据库访问的实现逻辑时,就不应该影响到领域层了。

所谓“正交”,并非二者之间没有关系,而是垂直相交的两条直线。唯一相关的依赖点是这两条直线的相交点,即两层之间的协作点。

保证同一层的组件处于同一个抽象层次。例如在一个基于元数据的多租户报表系统中,我们特别定义了一个引擎层(engine layer),这是一个隐喻,相当于为报表系统提供报表、实体与数据的驱动引擎。引擎层之下,是基础设施层,提供了多租户、数据库访问与元数据解析与管理等功能。在引擎层之上是一个控制层,通过该控制层的组件可以将引擎层的各个组件组合起来。分层架构的顶端是面向用户的用户展现层。如下图所示:

多租户报表系统

经典三层架构

什么是三层架构模型

三层架构模型

把整个业务应用划分为用户界面层(UI)、业务逻辑层(BLL)和数据访问层(DAL)三层结构,各层之间采用接口访问。

这种分层架构属于严格分层架构,即某层只能与位于其直接下方的层发生耦合,它有效地隔离了业务逻辑与数据访问逻辑,使得这两个不同关注点能够相对自由和独立地演化。

  • UI 即界面层,也叫表现层,用户界面层面向用户的体验与交互
  • BLL 即业务逻辑层,业务逻辑层面向应用与业务逻辑
  • DAL 即数据访问层,数据访问层面向各种外部资源与设备

什么是 MVC

MVC 开始是存在与桌面应用程序中的,M(Model)是业务模型、V(View)是用户界面、C(Controller)是控制器,使用 MVC 的目的是将 M 和 V 的实现代码分离,从而使同一个程序可以使用不同的形式。

MVC 强制性的使应用程序的输入、处理和输出分开。使用 MVC 应用程序被分为三个核心部件:模型、视图、控制器。

  • M 即 Model 模型层,负责处理业务逻辑以及数据库的交互;
  • V 即 View 视图层,负责显示数据和提交数据;
  • C 即 Controller 控制层,负责获取用户的输入、调用相应的业务逻辑进行数据封装,完成整个业务流程,将数据交给视图进行展示;

两者的区别

同样是架构,它们的相同之处在于表现层,都是用来负责显示数据和提交数据的。

不同之处在于另外两层,三层架构中没有定义 Controller 的概念,这是两者最大的区别。三层架构中当然也有 Model 层,但是两者的不同在于,MVC 中的 Model 层是由业务逻辑 + 数据访问共同组成;而三层架构中的 Model 是单指实体类。

传统三层架构设计流程

  1. 数据库设计,数据表如何建,表之间的关系如何设计
  2. 搭建数据访问层,如选一个 ORM 框架或者拼接 SQL 操作
  3. 业务逻辑的实现,由于先设计了数据库,整个的思考都会围绕着数据库,想着怎么写才能把数据正确地写入数据库中,这时 CRUD 的标准作法就出现了
  4. 表示层主要面向用户的输出

四层架构

根据 DDD 领域驱动设计原则,对应的软件架构也需要做出相应的调整,它有效的分离了业务复杂度与技术复杂度。

DDD 分层与传统三层区别

DDD分层与传统三层区别

架构设计

在 DDD 分层结构中将传统三层架构的业务逻辑层拆解为应用层和领域层。

建模方式

传统三层通常是以数据库为起点进行数据库分析设计,而 DDD 则需要以业务领域模型为核心建模(即面向对象建模方式),更能体现对现实世界的抽象。

故在 DDD 分层架构中 领域层 为系统的核心,包括所有的业务领域模型的抽象表达。

职责划分

持久化功能,其中原三层架构的数据访问层下沉到基础设施层的持久化机制实现,通用技术支持,一些公共通用技术支持也放到基础设施层去实现。

分层作用

分层 英文 描述
表现层 User Interface 用户界面层,或表现层,负责向用户显示解释用户命令。
用户可以是另一个计算机系统,不一定是使用用户界面的人。
应用层 Application 定义软件要完成的任务,并且指挥协调领域对象进行不同的操作。
该层不包含业务领域知识。
领域层 Domain 也称为模型层,系统的核心,负责表达业务概念,业务状态信息以及业务规则。
包含了该领域(问题域)所有复杂的业务知识抽象和规则定义。
基础设施层 Infrastructure 为领域模型提供持久化机制,当软件需要持久化能力时候才需要进行规划。
对其他层提供通用的技术支持能力,如消息通信,通用工具,配置等的实现。

四层架构设计流程

  1. 领域层:先从业务逻辑入手开始,设计时不再考虑数据库的实现。将以前的业务逻辑层(BLL)拆分成了领域层和应用层。领域层聚焦业务对象的业务逻辑实现,体现现实世界业务的逻辑变化。它用来表达业务概念、业务状态和业务规则。
  2. 应用层:应用层是领域层的上层,依赖领域层,是各聚合的协调和编排,原则上是不包括任何业务逻辑。它以较粗粒度的封闭为前端接口提供支持。除了提供上层调用外,还可以包括事件和消息的订阅。
  3. 用户接口层:面向用户访问的数据入向接口,可按不同场景提供不一样的用户接口实现。面向 Web 的可使用 http restful 的方式提供服务,可增加安全认证、权限校验,日志记录等功能;面向微服务的可使用 RPC 方式提供服务,可增加限流、熔断等功能。
  4. 基础设施层:是数据的出向接口,封装数据调用的技术细节。可为其它任意层提供服务,但为了解决耦合的问题采用了依赖倒置原则。其它层只依赖基础设施的接口,于具体实现进行分离。

编码实践

DDD 并没有给出标准的代码模型,按 DDD 分层架构的分层职责定义,在代码模型里分别为用户接口层、应用层、领域层和基础层,建立了 interfaces、application、domain 和 infrastructure 四个一级目录。

参考

如果觉得我的文章对您有用,请在支付宝公益平台找个项目捐点钱。 @Victor Jun 1, 2021

奉献爱心