分层架构
什么是分层架构
提到分层架构,大家最熟悉不过的当属三层架构了,由上至下分别为:表现层、业务逻辑层和数据访问层。三层架构十分受欢迎,首先是其足够简单,其次有效隔离了业务逻辑和数据访问逻辑,大大提高开发效率。其依赖关系如下图所示:

其中,每层的职责如下:
- 表现层:负责处理展示逻辑,负责向用户展示信息和接收用户的指令。
- 业务逻辑层:负责表达业务用例,处理业务逻辑。
- 数据访问层:负责数据访问逻辑,与数据库打交道。
从上图来看,分层架构具有以下特点:
- 单向单层依赖
- 每层职责单一
- 对软件结构的横向切分
根据以上特点那我们尝试来给分层架构下个定义:
分层架构是将系统根据职责进行横向切分,形成清晰的逻辑分层结构,以降低系统复杂度。
为什么需要分层
如果一个项目,开始之初为了快速开发和验证,使用MVC框架,在一个单独项目从前端到数据库,一撸到底,开发效率无所质疑。我们知道,一切不变的是变化,随着功能需求的迭代,难免会陷入改动的泥潭,牵一发而动全身。为了隔离变化,就必须合理的组织代码结构。那么分层就是一个很好的解决方案。分层架构通过职责分离,也就是关注点分离,指导我们进行合理的进行代码组织,来降解系统复杂度,方便我们开发出高内聚、低耦合、可复用和易维护的软件系统:
- 高内聚:每一层只负责一个职责,职责边界清晰,每一层专注当前层进行合理封装抽象。
- 低耦合:单向依赖,上层只能依赖于下层,没有循环依赖。
- 可复用:下层逻辑可供上层多次复用。
- 易维护:每一层专注当前层的修改。
总而言之,分层的核心目的还是为了降解系统复杂度,提高系统的健壮性和可维护性。这也就是为什么需要分层的原因。
然而分层架构固然很好,但前提是分层合理。否则,系统复杂度不降反升,开发效率也将大大折扣。因此在分层设计时,要结合系统规模和业务复杂度,参照经典的分层架构模式,并遵循最佳实践,进行合理分层。接下来我们就来看一看ABP 是如何进行合理分层的。
ABP 分层架构的设计
如果从创建的解决方案来看,包含很多个项目,乍一看,有点懵,只是分层分的比较细罢了,其层次结构如下图所示,如果了解过DDD经典的分层架构,可以一眼看出端倪。是的,ABP正是参照了DDD的经典四层架构进行分层。下面就来拆解下ABP的分层架构。

从上图可知,主要包含以下四层:
- 表现层:负责处理展示逻辑,负责向用户展示信息和接收用户的指令。同三层架构的表现层。
- 应用层:负责表达业务用例,组装领域层的业务逻辑提供组合服务供表现层消费。
- 领域层:负责处理业务逻辑,表达业务概念,业务状态信息以及业务规则。
- 基础设施层:为其他层提供基础能力。比如,对领域层进行持久化,对应用层提供事务控制,等等。
相较于经典的三层架构,四层架构将三层架构的业务逻辑层一分为二,同时将数据访问层下放到提供基础能力的基础设施层。
分层架构,主要有两种表现形式:严格分层和松散分层。这两种形式,都是单向依赖,无循环依赖,区别在于每一层是否仅依赖当前层的下一层。在严格分层架构中,每一层只能依赖当前层的下一层,而在松散分层架构中,则允许每一层可以依赖当前层的任意下层,区别如下图所示。
那ABP属于哪一种呢?现在还不好下结论。要想很好的理解ABP的架构设计,那SOLID设计原则,就不可不知。
- S,Single Responsibility,单一职责原则:拆分出的每一个项目,职责单一,清晰明确。
Domain.Shared
主要用来定义共享对象,比如常量 - O,Open Closed,开发封闭原则:对扩展开发,对修改封闭,每个项目因为职责单一,修改范围可控。
- L,里氏替换原则:父类出现的地方,可以用子类替换,反之不行。
- I,Interface Separation,接口隔离原则:
- D,依赖反转原则:高层模块不应该依赖底层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
再回过头来看上面的层次结构,会发现以下问题就一目了然了:
-
基础设施层位于最底层,为什么却反向依赖领域层?
依赖反转原则的体现。 -
领域层拆分出
Domain.Shared
的目的是什么?
单一职责原则和开放封闭原则的体现。 -
应用层拆分出
Application.Contract
的目的是什么?
单一职责原则、接口隔离原则和开放封闭原则的体现。 -
表现层中定义额外的
HttpApi
和HttpApi.Client
的目的是什么?
单一职责,开放封闭原则的体现。
因此ABP的分层架构,更像是基于经典四层架构演进的结果,请看下图:

看了这张图,如果按照松散型和严格型的定义,整体来看,ABP是松散型分层架构。但如果单独把基础设施层拿掉,也就是说按照模板项目代码结构来看,其又是严格型分层架构。基础设施层,ABP是以模块的形式提供,应用按需依赖的,所以这一层对开发来说是半透明的。因此,实际开发过程中,严格遵守严格型分层架构的规范进行开发就好,确保每一层严守边界,各司其职。
简洁架构
而如果将基础设施层以环形包围,以上的分层架构就演变为了简洁架构,每一层只依赖于它内部的层。最独立的层显示在最内部的圆圈中,就是领域层。

其中由内而外:
- Entities:表达企业业务规则,对应的是领域层
- Use Cases:表达应用业务规则,对应的是应用层
- Gateways、Presenters、Controllers:对应的是表现层,用于对外暴露网关、接口。
- DB、Device、Web:对应基础设施层。