分层架构模式,最常见的架构模式。在 Java EE 应用开发实践中,分层架构模式已经是事实上的标准。

模式介绍

分层架构模式中的每一层通常是水平的,并且在整个应用中有着特定的角色(比如负责展示、负责业务逻辑等)。虽然不同的业务场景分层不一样,但是分层架构模式通常有四层,表现层(presentation)、业务逻辑层(business)、持久化层(persistence)和数据库层(database),如下图。

分层架构模式

每一层都有特定的职责。比如表现层负责处理 UI 展示以及与浏览器之间的交互,而业务逻辑层则负责处理具体的业务逻辑。每一层都针对其负责的职责进行了一定的抽象,并且仅对此负责。比如业务逻辑层只关心如何处理好业务请求,不关心 UI 究竟是如何展示的。业内有一个专业术语,叫关注点分离(separation of concerns),表达的意思是一样的。

一些关键概念

封闭层

上图中,每一层都被标记为是封闭的(closed)。这是分层架构模式中非常重要的一个概念。意思是说,用户请求如果要从上层去到下层,则必须一层一层的穿过中间的所有层。比如一个用户请求必须要先经过表现层,然后经过业务逻辑层,再经过持久化层,最终到达数据库层。

那为什么不能直接从表现层直接到达数据库层呢?毕竟这样有着更好的性能。这就要引入隔离层(layers of isolation)的概念了。隔离层要求某一层中变化的影响范围尽量保持在当前层内,或者仅仅影响到与之相邻的层。比如数据库层的变化,影响范围尽量保持在数据库层内,或者仅仅影响到持久化层(当持久化层中存在直接通过 SQL 操作数据库的情况时)。

如果不加这层限制的话,比如允许表现层直接操作数据库,那么当数据库层发生变更时,表现层也会受到影响,这样每一层之间就会存在强烈的耦合。这样就是的整个架构后期很难维护和迭代。

同时,隔离层也意味着每一层都是独立的,对其它层的内部细节知之甚少。当我们需要重构表现层时,因为每个分层都是独立的,我们可以直接复用业务逻辑层。

虽然封闭层有助于实现隔离层,因此有助于隔离架构内的变化,但有时开放某些层是有意义的。

比如,当我们有一些公共服务模块(数据、字符串处理类,审计和日志类等)要提供给业务逻辑层使用。最好的做法是引入一个公共服务层。因为这样可以很好的在架构层面避免其他层使用公共服务层的逻辑。

但是这么做又有明显的缺点,那就是由于封闭性,所有的用户请求都要从公共服务层经过,而很多时候这是多余的。开放层(open layer)可以帮助我们解决这个问题。

开放层

如上图所示,公共服务层被标记为开放的,这样业务逻辑层就可以穿过公共服务层直接访问持久化层。

利用好开放层和封闭层的概念有助于定义清楚架构中的每一层和请求流之间的关系,并为设计人员和开发人员提供必要的信息,以了解架构内的各种层间访问限制。

举例说明

假设一个用户请求查询特定个人的客户信息,如下图所示。黑色箭头表示向下流向数据库以查询客户数据的请求,红色箭头表示向上流向屏幕以显示数据的响应。

分层架构样例

在此例中,客户信息由客户数据和订单数据(客户下的订单)组成。客户屏幕负责接受请求并显示客户信息。它不知道数据在哪里,如何查询,或者必须查询多少个数据库表才能获取数据。一旦表现层收到获取特定个人客户信息的请求,它就会将该请求转发到客户委托模块(Customer Delegate)。该模块了解业务层中的哪些模块可以处理该请求,如何访问这些模块以及它需要哪些数据。

业务逻辑层中的客户对象负责聚合业务请求所需的所有信息(在本例中是获取客户信息)。该模块调用持久层中的 customer dao(数据访问对象)模块获取客户数据,同时调用 order dao 模块获取订单信息。这些模块依次执行 SQL 语句以检索相应的数据并将其传回业务逻辑层中的客户对象。

一旦客户对象接收到数据,它就会聚合数据并将该信息传回给客户委托模块,然后客户委托模块将该数据传递给客户屏幕以呈现给用户。

从技术角度来说,每一层的具体实现方式不受限制,可以由团队根据自身的技术特定和实际的业务需求自行决定。

其他说明

分层架构模式是一种可靠的通用模式。但是也有两个问题需要注意。

第一个问题是反模式问题。比如如果我们的分层中很多都是直接透传,比如表现层访问业务逻辑层,而业务逻辑层实际上什么事情也没做,直接透传给了持久化层,最后达到数据库层,然后数据再同样反向返回回来。

如何来解决这样的问题呢?可以参考一下二八原则。也就是说,如果有百分之八十的情况下,业务请求在每一层都有处理逻辑的,百分之二十的情况下存在透传场景,那么可以认为分层是合理的。如果超过百分之二十的场景都需要透传,那么可以考虑将某些层标记为开放的。

第二个问题是分层架构模式通常最后会导致巨石应用的问题。即使我们在每一层都划分了独立模块,可以独立部署。对于某些应用来说,分层架构模式确实在部署、总体健壮性和可靠性、性能和可扩展性方面存在一些潜在问题。

思考

分层架构模式是比较常见的架构模式,每一层的职责明确,通常也与人员的组织架构相匹配(康威定律)。同时因为隔离层的特性,结合开放层和封闭层,可以很好的实现业务需求,同时保持一定的独立性。在是否易于测试、是否易于开发等方面表现出了一定的优势。

但是,因为通常业务实现都具有整体性,即使我们划分的层,每一层划分了独立模块,但是分层架构模式在如何解决模块之间的紧耦合方面没能给出很好的解法,从而最终导致应用在快速响应环境变化、是否易于部署、可扩展性等方面表现出了一定的弱势。

另外,由于分层的存在,不可避免的对应用性能将产生一定的影响。

关注微信公众号,获取最新推送~

加微信,深入交流~