本文由 简悦 SimpRead 转码, 原文地址 www.oreilly.com

Chapter 1. Layered Architecture The most common architecture pattern is the layered architecture pat……

Chapter 1. Layered Architecture

第一章分层架构

The most common architecture pattern is the layered architecture pattern, otherwise known as the n-tier architecture pattern. This pattern is the de facto standard for most Java EE applications and therefore is widely known by most architects, designers, and developers. The layered architecture pattern closely matches the traditional IT communication and organizational structures found in most companies, making it a natural choice for most business application development efforts. 

最常见的架构模式是分层架构模式,也称为 n 层架构模式。这种模式是大多数 JavaEE 应用程序的行业标准,因此为大多数架构师、设计师和开发人员所熟知。分层体系结构模式与大多数公司中的传统 IT 通信和组织结构非常匹配,这使其成为大多数业务应用程序开发工作的自然选择。 

Pattern Description

模式描述

Components within the layered architecture pattern are organized into horizontal layers, each layer performing a specific role within the application (e.g., presentation logic or business logic). Although the layered architecture pattern does not specify the number and types of layers that must exist in the pattern, most layered architectures consist of four standard layers: presentation, business, persistence, and database (Figure 1-1). In some cases, the business layer and persistence layer are combined into a single business layer, particularly when the persistence logic (e.g., SQL or HSQL) is embedded within the business layer components. Thus, smaller applications may have only three layers, whereas larger and more complex business applications may contain five or more layers. 

分层体系结构模式中的组件被组织成水平层,每个层在应用程序中执行特定的角色 (例如,表示逻辑或业务逻辑)。尽管分层架构模式没有指定模式中必须存在的层的数量和类型,但是大多数分层架构由四个标准层组成: 表示层、业务层、持久层和数据库层(图 1-1)。在某些情况下,业务层和持久层合并为一个业务层,特别是当持久化逻辑(例如 SQL 或 HSQL) 嵌入到业务层组件中时。因此,较小的应用程序可能只有三层,而较大和更复杂的业务应用程序可能包含五层或更多层。 

Each layer of the layered architecture pattern has a specific role and responsibility within the application. For example, a presentation layer would be responsible for handling all user interface and browser communication logic, whereas a business layer would be responsible for executing specific business rules associated with the request. Each layer in the architecture forms an abstraction around the work that needs to be done to satisfy a particular business request. For example, the presentation layer doesn’t need to know or worry about how to get customer data; it only needs to display that information on a screen in particular format. Similarly, the business layer doesn’t need to be concerned about how to format customer data for display on a screen or even where the customer data is coming from; it only needs to get the data from the persistence layer, perform business logic against the data (e.g., calculate values or aggregate data), and pass that information up to the presentation layer.  

分层架构模式的每一层在应用程序中都有特定的角色和职责。例如,表示层负责处理所有用户界面和浏览器通信逻辑,而业务层负责执行与请求相关的特定业务规则。体系结构中的每一层都围绕满足特定业务请求所需完成的工作形成一个抽象。例如,表示层不需要知道或担心如何获取客户数据; 它只需要在屏幕上以特定的格式显示该信息。类似地,业务层不需要关心如何格式化客户数据以便在屏幕上显示,甚至不需要关心客户数据来自哪里; 它只需要从持久层获取数据,对数据执行业务逻辑 (例如,计算值或聚合数据) ,并将该信息传递给表示层。  

Figure 1-1. Layered architecture pattern
图 1-1 分层架构模式

One of the powerful features of the layered architecture pattern is the separation of concerns among components. Components within a specific layer deal only with logic that pertains to that layer. For example, components in the presentation layer deal only with presentation logic, whereas components residing in the business layer deal only with business logic. This type of component classification makes it easy to build effective roles and responsibility models into your architecture, and also makes it easy to develop, test, govern, and maintain applications using this architecture pattern due to well-defined component interfaces and limited component scope.

分层架构模式的一个强大特性是组件之间的关注点分离。特定层中的组件只处理属于该层的逻辑。例如,表示层中的组件只处理表示逻辑,而业务层中的组件只处理业务逻辑。这种类型的组件分类使得在体系结构中构建有效的角色和职责模型变得非常容易,而且由于定义良好的组件接口和有限的组件范围,使得使用这种体系结构模式开发、测试、治理和维护应用程序变得非常容易。

Key Concepts

关键概念

Notice in Figure 1-2 that each of the layers in the architecture is marked as being closed. This is a very important concept in the layered architecture pattern. A closed layer means that as a request moves from layer to layer, it must go through the layer right below it to get to the next layer below that one. For example, a request originating from the presentation layer must first go through the business layer and then to the persistence layer before finally hitting the database layer. 

注意,在图 1-2 中,体系结构中的每个层都被标记为已关闭。这是分层架构模式中的一个非常重要的概念。封闭层意味着当一个请求从一个层移动到另一个层时,它必须通过它下面的层才能到达下一个层。例如,来自表示层的请求必须首先经过业务层,然后到达持久层,最后才能到达数据库层。 

Figure 1-2. Closed layers and request access
图 1-2。封闭层和请求访问

So why not allow the presentation layer direct access to either the persistence layer or database layer? After all, direct database access from the presentation layer is much faster than going through a bunch of unnecessary layers just to retrieve or save database information. The answer to this question lies in a key concept known as layers of isolation

那么,为什么不允许表示层直接访问持久层或数据库层呢?毕竟,从表示层直接访问数据库要比仅仅为了检索或保存数据库信息而穿过一大堆不必要的层快得多。这个问题的答案在于一个被称为隔离层的关键概念。 

The layers of isolation concept means that changes made in one layer of the architecture generally don’t impact or affect components in other layers: the change is isolated to the components within that layer, and possibly another associated layer (such as a persistence layer containing SQL). If you allow the presentation layer direct access to the persistence layer, then changes made to SQL within the persistence layer would impact both the business layer and the presentation layer, thereby producing a very tightly coupled application with lots of interdependencies between components. This type of architecture then becomes very hard and expensive to change.  

隔离层的概念意味着在体系结构的一个层中所做的更改通常不会影响或影响其他层中的组件: 这个更改被隔离到该层中的组件,可能还有另一个相关联的层 (比如包含 SQL 的持久层)。如果允许表示层直接访问持久层,那么对持久层中的 SQL 所做的更改将同时影响业务层和表示层,从而产生一个具有组件之间大量相互依赖性的非常紧密耦合的应用程序。这种类型的体系结构变得非常困难和昂贵的改变。  

The layers of isolation concept also means that each layer is independent of the other layers, thereby having little or no knowledge of the inner workings of other layers in the architecture. To understand the power and importance of this concept, consider a large refactoring effort to convert the presentation framework from JSP (Java Server Pages) to JSF (Java Server Faces). Assuming that the contracts (e.g., model) used between the presentation layer and the business layer remain the same, the business layer is not affected by the refactoring and remains completely independent of the type of user-interface framework used by the presentation layer.  

隔离层的概念还意味着每一层独立于其他层,因此对体系结构中其他层的内部工作原理知之甚少或根本不知道。为了理解这个概念的力量和重要性,请考虑进行大规模的重构工作,将表示框架从 JSP (Java Server Pages)转换为 JSF (Java Server Faces)。假设表示层和业务层之间使用的契约 (例如,模型) 保持不变,业务层不受重构的影响,并且完全独立于表示层使用的用户界面框架的类型。  

While closed layers facilitate layers of isolation and therefore help isolate change within the architecture, there are times when it makes sense for certain layers to be open. For example, suppose you want to add a shared-services layer to an architecture containing common service components accessed by components within the business layer (e.g., data and string utility classes or auditing and logging classes). Creating a services layer is usually a good idea in this case because architecturally it restricts access to the shared services to the business layer (and not the presentation layer). Without a separate layer, there is nothing architecturally that restricts the presentation layer from accessing these common services, making it difficult to govern this access restriction.  

虽然封闭层有助于隔离层,因此有助于隔离体系结构中的更改,但有时候某些层开放是有意义的。例如,假设您希望将共享服务层添加到一个体系结构中,该体系结构包含由业务层中的组件访问的公共服务组件 (例如,数据和字符串实用工具类或审计和日志记录类)。在这种情况下,创建服务层通常是一个好主意,因为在体系结构上,它将对共享服务的访问限制在业务层 (而不是表示层)。如果没有单独的层,那么在体系结构上就不存在任何限制表示层访问这些公共服务的东西,这使得很难控制这种访问限制。  

In this example, the new services layer would likely reside below the business layer to indicate that components in this services layer are not accessible from the presentation layer. However, this presents a problem in that the business layer is now required to go through the services layer to get to the persistence layer, which makes no sense at all. This is an age-old problem with the layered architecture, and is solved by creating open layers within the architecture.  

在这个示例中,新的服务层可能位于业务层之下,以指示此服务层中的组件不能从表示层访问。但是,这样就出现了一个问题,业务层现在需要穿过服务层才能到达持久层,这是毫无意义的。这是分层体系结构的一个古老问题,可以通过在体系结构中创建开放层来解决。  

As illustrated in Figure 1-3, the services layer in this case is marked as open,  meaning requests are allowed to bypass this open layer and go directly to the layer below it. In the following example, since the services layer is open, the business layer is now allowed to bypass it and go directly to the persistence layer, which makes perfect sense.  

如图 1-3 所示,在这种情况下,服务层被标记为打开的,这意味着请求可以绕过这个打开的层,直接进入它下面的层。在下面的示例中,因为服务层是开放的,所以现在允许业务层绕过它,直接进入持久层,这非常有意义。  

Figure 1-3. Open layers and request flow
图 1-3。打开层和请求流

Leveraging the concept of open and closed layers helps define the relationship between architecture layers and request flows and also provides designers and developers with the necessary information to understand the various layer access restrictions within the architecture. Failure to document or properly communicate which layers in the architecture are open and closed (and why) usually results in tightly coupled and brittle architectures that are very difficult to test, maintain, and deploy.

利用开放和封闭层的概念有助于定义体系结构层和请求流之间的关系,并为设计人员和开发人员提供必要的信息,以理解体系结构中各种层访问限制。如果不能记录或正确地交流架构中的哪些层是开放和关闭的 (以及为什么) ,通常会导致紧密耦合和脆弱的架构,这些架构很难测试、维护和部署。

Pattern Example

模式示例

To illustrate how the layered architecture works, consider a request from a business user to retrieve customer information for a particular individual as illustrated in Figure 1-4. The black arrows show the request flowing down to the database to retrieve the customer data, and the red arrows show the response flowing back up to the screen to display the data. In this example, the customer information consists of both customer data and order data (orders placed by the customer).  

为了说明分层架构是如何工作的,考虑一个来自业务用户的请求,为一个特定的个人检索客户信息,如图 1-4 所示。黑色箭头显示流向数据库以检索客户数据的请求,红色箭头显示流回屏幕以显示数据的响应。在此示例中,客户信息由客户数据和订单数据 (由客户下达的订单) 组成。  

The customer screen is responsible for accepting the request and displaying the customer information. It does not know where the data is, how it is retrieved, or how many database tables must be queries to get the data. Once the customer screen receives a request to get customer information for a particular individual, it then forwards that request onto the customer delegate module. This module is responsible for knowing which modules in the business layer can process that request and also how to get to that module and what data it needs (the contract). The customer object in the business layer is responsible for aggregating all of the information needed by the business request (in this case to get customer information). This module calls out to the customer dao (data access object) module in the persistence layer to get customer data, and also the order dao module to get order information. These modules in turn execute SQL statements to retrieve the corresponding data and pass it back up to the customer object in the business layer. Once the customer object receives the data, it aggregates the data and passes that information back up to the customer delegate, which then passes that data to the customer screen to be presented to the user.      

客户屏幕负责接受请求并显示客户信息。它不知道数据在哪里,如何检索数据,或者必须查询多少个数据库表才能获得数据。一旦客户屏幕接收到为特定个人获取客户信息的请求,它就会将该请求转发到客户委托模块。该模块负责了解业务层中哪些模块可以处理该请求,以及如何访问该模块和它需要什么数据 (契约)。业务层中的客户对象负责聚合业务请求所需的所有信息(在本例中是为了获取客户信息)。该模块调用持久层中的客户道(数据访问对象) 模块来获取客户数据,同时调用订单道模块来获取订单信息。这些模块依次执行 SQL 语句来检索相应的数据,并将其传递回业务层中的客户对象。一旦客户对象接收到数据,它就会聚合数据并将该信息传递回客户委托,然后委托将该数据传递到客户屏幕,以呈现给用户。      

Figure 1-4. Layered architecture example
图 1-4。分层架构示例

From a technology perspective, there are literally dozens of ways these modules can be implemented. For example, in the Java platform, the customer screen can be a (JSF) Java Server Faces screen coupled with the customer delegate as the managed bean component. The customer object in the business layer can be a local Spring bean or a remote EJB3 bean. The data access objects illustrated in the previous example can be implemented as simple POJO’s (Plain Old Java Objects), MyBatis XML Mapper files, or even objects encapsulating raw JDBC calls or Hibernate queries. From a Microsoft platform perspective, the customer screen can be an ASP (active server pages) module using the .NET framework to access C# modules in the business layer, with the customer and order data access modules implemented as ADO (ActiveX Data Objects). 

从技术的角度来看,实现这些模块的方法有几十种。例如,在 Java 平台中,客户屏幕可以是 (JSF) JavaServerFaces 屏幕,客户委托作为托管 bean 组件耦合在一起。业务层中的客户对象可以是本地 Spring bean 或远程 EJB3 bean。前面示例中说明的数据访问对象可以实现为简单的 POJO (普通的旧 Java 对象)、 MyBatis XML Mapper 文件,甚至是封装原始 JDBC 调用或 Hibernate 查询的对象。从 Microsoft 平台的角度来看,客户界面可以是一个 ASP (活动服务器页) 模块,使用。NET 框架访问业务层的 C # 模块,客户和订单数据访问模块实现为 ADO (ADO)。 

Considerations

考虑因素

The layered architecture pattern is a solid general-purpose pattern, making it a good starting point for most applications, particularly when you are not sure what architecture pattern is best suited for your application. However, there are a couple of things to consider from an architecture standpoint when choosing this pattern.

分层架构模式是一个坚实的通用模式,对于大多数应用程序来说,它是一个很好的起点,特别是当您不确定什么架构模式最适合您的应用程序时。然而,在选择这种模式时,从体系结构的角度来看,有一些事情需要考虑。

The first thing to watch out for is what is known as the architecture sinkhole anti-pattern. This anti-pattern describes the situation where requests flow through multiple layers of the architecture as simple pass-through processing with little or no logic performed within each layer. For example, assume the presentation layer responds to a request from the user to retrieve customer data. The presentation layer passes the request to the business layer, which simply passes the request to the persistence layer, which then makes a simple SQL call to the database layer to retrieve the customer data. The data is then passed all the way back up the stack with no additional processing or logic to aggregate, calculate, or transform the data. 

首先要注意的是所谓的建筑陷坑反模式。这个反模式描述了这样一种情况,即请求流通过体系结构的多个层,作为简单的传递处理,在每个层中很少或根本不执行逻辑。例如,假设表示层响应来自用户的检索客户数据的请求。表示层将请求传递给业务层,业务层只是将请求传递给持久层,然后持久层对数据库层执行一个简单的 SQL 调用以检索客户数据。然后将数据一路传递回堆栈,不需要额外的处理或逻辑来聚合、计算或转换数据。 

Every layered architecture will have at least some scenarios that fall into the architecture sinkhole anti-pattern. The key, however, is to analyze the percentage of requests that fall into this category. The 80-20 rule is usually a good practice to follow to determine whether or not you are experiencing the architecture sinkhole anti-pattern. It is typical to have around 20 percent of the requests as simple pass-through processing and 80 percent of the requests having some business logic associated with the request. However, if you find that this ratio is reversed and a majority of your requests are simple pass-through processing, you might want to consider making some of the architecture layers open, keeping in mind that it will be more difficult to control change due to the lack of layer isolation. 

每个分层体系结构都至少有一些场景落入体系结构陷坑反模式。但是,关键是要分析属于这一类别的请求的百分比。80-20 规则通常是一个很好的实践,可以用来确定您是否正在经历体系结构陷坑反模式。通常有大约 20% 的请求作为简单的传递处理,80% 的请求具有与请求相关联的一些业务逻辑。但是,如果您发现这个比例是相反的,并且您的大多数请求都是简单的传递处理,那么您可能需要考虑开放一些架构层,请记住,由于缺乏层隔离,控制更改将更加困难。 

Another consideration with the layered architecture pattern is that it tends to lend itself toward monolithic applications, even if you split the presentation layer and business layers into separate deployable units. While this may not be a concern for some applications, it does pose some potential issues in terms of deployment, general robustness and reliability, performance, and scalability.   

分层体系结构模式的另一个考虑因素是,即使您将表示层和业务层划分为单独的可部署单元,它也倾向于使用单一应用程序。虽然这可能不是某些应用程序所关心的问题,但是它确实在部署、一般的健壮性和可靠性、性能和可伸缩性方面提出了一些潜在的问题。   

Pattern Analysis

模式分析

The following table contains a rating and analysis of the common architecture characteristics for the layered architecture pattern. The rating for each characteristic is based on the natural tendency for that characteristic as a capability based on a typical implementation of the pattern, as well as what the pattern is generally known for. For a side-by-side comparison of how this pattern relates to other patterns in this report, please refer to Appendix A at the end of this report.

下表对分层架构模式的常见架构特征进行了评级和分析。每个特征的评级基于该特征的自然趋势,即基于模式的典型实现的功能,以及模式通常为人所知的功能。关于这种模式与本报告中其他模式的并行比较,请参阅本报告末尾的附录 A。

Overall agility

整体灵活性

Rating: Low

评分: 低

Analysis: Overall agility is the ability to respond quickly to a constantly changing environment. While change can be isolated through the layers of isolation feature of this pattern, it is still cumbersome and time-consuming to make changes in this architecture pattern because of the monolithic nature of most implementations as well as the tight coupling of components usually found with this pattern.

分析: 总体敏捷性是对不断变化的环境作出快速反应的能力。虽然可以通过这个模式的隔离特性层来隔离变更,但是在这个架构模式中进行变更仍然是非常麻烦和耗时的,因为大多数实现的单一性以及通常与这个模式相关的组件之间的紧密耦合。

Ease of deployment

易于部署

Rating: Low

评分: 低

Analysis: Depending on how you implement this pattern, deployment can become an issue, particularly for larger applications. One small change to a component can require a redeployment of the entire application (or a large portion of the application), resulting in deployments that need to be planned, scheduled, and executed during off-hours or on weekends. As such, this pattern does not easily lend itself toward a continuous delivery pipeline, further reducing the overall rating for deployment.

分析: 根据您实现此模式的方式,部署可能成为一个问题,特别是对于较大的应用程序。对组件的一个小更改可能需要重新部署整个应用程序 (或应用程序的大部分) ,导致需要在非工作时间或周末计划、安排和执行部署。因此,这种模式不容易适用于持续交付管道,从而进一步降低了部署的总体评级。

Testability

可测试性

Rating: High

收视率: 高

Analysis: Because components belong to specific layers in the architecture, other layers can be mocked or stubbed, making this pattern is relatively easy to test. A developer can mock a presentation component or screen to isolate testing within a business component, as well as mock the business layer to test certain screen functionality.

分析: 因为组件属于体系结构中的特定层,所以其他层可以被模拟或存根化,这使得该模式相对容易测试。开发人员可以模拟表示组件或屏幕来隔离业务组件中的测试,也可以模拟业务层来测试某些屏幕功能。

Performance

表演

Rating: Low

评分: 低

Analysis: While it is true some layered architectures can perform well, the pattern does not lend itself to high-performance applications due to the inefficiencies of having to go through multiple layers of the architecture to fulfill a business request.

分析: 虽然一些分层架构确实可以很好地执行,但是由于必须通过多层架构来满足业务请求的效率低下,这种模式不适合高性能应用程序。

Scalability

可伸缩性

Rating: Low

评分: 低

Analysis: Because of the trend toward tightly coupled and monolithic implementations of this pattern, applications build using this architecture pattern are generally difficult to scale. You can scale a layered architecture by splitting the layers into separate physical deployments or replicating the entire application into multiple nodes, but overall the granularity is too broad, making it expensive to scale.

分析: 由于这种模式的紧密耦合和单片实现的趋势,使用这种体系结构模式构建的应用程序通常难以扩展。您可以通过将层划分为单独的物理部署或将整个应用程序复制到多个节点来扩展分层体系结构,但总体而言粒度太大,因此扩展成本很高。

Ease of development

易于开发

Rating: High

收视率: 高

Analysis: Ease of development gets a relatively high score, mostly because this pattern is so well known and is not overly complex to implement. Because most companies develop applications by separating skill sets by layers (presentation, business, database), this pattern becomes a natural choice for most business-application development. The connection between a company’s communication and organization structure and the way it develops software is outlined is what is called Conway’s law. You can Google “Conway’s law” to get more information about this fascinating correlation.

分析: 易于开发得到了相对较高的分数,主要是因为这种模式是众所周知的,并且实现起来不会过于复杂。因为大多数公司通过按层 (表示、业务、数据库) 分离技能集来开发应用程序,所以这种模式成为大多数业务应用程序开发的自然选择。一个公司的沟通和组织结构与它开发软件的方式之间的联系被概述为所谓的康威定律。你可以在谷歌上搜索 “康威定律” 来获得更多关于这种迷人的相关性的信息。