An Introduction to the layered architecture

Important concepts

The layered architecture is a common architectural style with several key concepts that define its structure and behavior. These concepts include:

  • Horizontal Layers: The architecture is organized into horizontal layers, each with a specific role within the application. Common layers include presentation, business, persistence, and database. The number of layers can vary depending on the application’s complexity.
  • Separation of Concerns: Components within a specific layer deal only with logic that pertains to that layer. This means that, for example, presentation layer components handle user interface logic, and business layer components handle business rules.
  • Abstraction: Each layer forms an abstraction around the work needed to satisfy a business request. For example, the presentation layer doesn’t need to know how to get data, and the business layer doesn’t need to know how to format it for display.
  • Open vs. Closed Layers: Layers can be either closed or open.
    • Closed layers require a request to pass through the layer directly below it to reach the next layer. This provides layers of isolation. For example, a request from the presentation layer must go through the business layer and then the persistence layer before hitting the database layer.
    • Open layers allow requests to bypass the layer directly below it. This is useful when shared services are implemented, allowing the business layer to bypass the shared service layer to get to the persistence layer.
  • Layers of Isolation: Changes made in one layer generally do not impact components in other layers. This is achieved by isolating changes within a specific layer. For example, replacing a user interface framework in the presentation layer shouldn’t affect the business layer if the contracts between the layers remain the same.
  • Request Flow: Requests typically flow down the layers (e.g., from presentation to database), and the response flows back up. Each layer processes its part of the request and then passes it to the next layer.
  • Component Communication: Layers communicate via well-defined component interfaces and contracts. For example, the presentation layer uses a customer delegate to invoke methods in the business layer.
  • Technical Partitioning: The layered architecture is a technically partitioned architecture, which aligns with team structures organized by technical domains. This means teams may be divided into UI developers, backend developers, and database teams.
  • Anti-Pattern: The layered architecture can lead to an “architecture sinkhole anti-pattern”. This occurs when requests flow through multiple layers with little or no processing at each layer. When most requests are simple pass-through processing, you might want to consider open layers.

These concepts work together to provide a structured and organized approach to building applications. The layered architecture is a well-understood approach, making it a good starting point for many projects. However, it is important to consider its limitations such as scalability and agility when determining whether this is the right architecture for your project.

Questions and Answers

What is a layered architecture and why is it so commonly used?

A layered architecture, also known as an n-tier architecture, organizes an application into horizontal layers, each with a specific role. Common layers include presentation, business, persistence, and database. It’s a popular choice because it aligns well with traditional IT team structures organized by technical domains (e.g., front-end, back-end, database). Its widespread familiarity makes it a natural starting point for many projects.

What are the typical layers in a layered architecture and what are their responsibilities?

Typical layers in layered architecture

A typical layered architecture includes:

  • Presentation Layer: Handles user interface and browser communication logic. It’s responsible for displaying information to the user.
  • Business Layer: Implements the business rules and logic associated with a request. It manipulates data received from the persistence layer.
  • Persistence Layer: Responsible for interacting with the data storage mechanisms, often dealing with SQL or data access objects (DAOs).
  • Database Layer: The actual data storage, which could be a relational database or a NoSQL system.

Each layer abstracts away details of the layers below, so the presentation layer, for example, doesn’t need to know how data is retrieved, only how to display it.

What does it mean for a layer to be “closed,” and why is this important?

A closed layer means that a request must pass through every layer below it to reach the destination. For example, a request from the presentation layer must go through the business layer and then the persistence layer before reaching the database.

Demonstration of closed layers

This concept is crucial for “layers of isolation.” It isolates changes to specific layers, preventing modifications in one layer from unexpectedly affecting other parts of the system. This makes the application more maintainable and less brittle.

What does it mean for a layer to be “open,” and when is it useful?

An open layer allows requests to bypass it and go directly to the layer below. This can be useful when introducing a shared services layer for common functionalities such as logging.

Open layer

By making the services layer open, the business layer can bypass it to reach the persistence layer when necessary. This allows for logical separation and access control for shared resources, without enforcing unnecessary hops.

What is the “architecture sinkhole” anti-pattern, and why should it be avoided?

The “architecture sinkhole” anti-pattern occurs when requests pass through multiple layers with little or no logic being performed in each layer. For example, a request might pass from the presentation layer to the business layer to the persistence layer, and then to the database without any actual work being done until the database is reached. This pattern reduces the value of the layers, makes the system inefficient and makes layers become simple pass-through conduits. If most requests follow this pattern, it indicates the architecture might not be well-suited for the application’s needs and should be examined further.

What are the advantages of using a layered architecture?

The layered architecture offers several benefits, including:

  • Simplicity and Familiarity: It’s well-understood, making it easy for developers and architects to learn and implement.
  • Modularity and Separation of Concerns: Each layer is responsible for specific functionality, leading to a clearer, more organized codebase.
  • Maintainability and Testability: Changes to one layer are less likely to affect others. This makes testing easier.
  • Good starting point: It is useful if you are unsure which architecture is suitable for your project.
  • Alignment with team structures: If your team is organized by technical domains, this architecture style fits well.
  • Isolated Changes: Changes are often limited to a specific layer making maintenance and feature development easier in many situations.

When should you avoid using a layered architecture?

While the layered architecture has several advantages, it’s not suitable in all situations. Avoid it when:

  • High operational concerns: The monolithic nature of the layered architecture makes it difficult to scale, is not fault tolerant, and impacts performance.
  • Domain-level changes are frequent: if most of your changes affect multiple layers of the system (business, persistence, presentation), the layered architecture makes change difficult to manage.
  • Cross-functional domain-based teams: If your development teams are organized into domain teams with cross-functional abilities, the technical partitioning of a layered architecture will make development and integration more difficult.

How does the layered architecture handle a typical request, like retrieving customer data?

In a typical request to retrieve customer data, the following happens:

  1. The presentation layer receives the request (e.g., from a user interface).
  2. It delegates the request to the corresponding module in the business layer.
  3. The business layer module aggregates data from different sources.
  4. It calls the appropriate modules (Data Access Objects, or DAOs) in the persistence layer.
  5. The persistence layer executes database queries.
  6. Data flows back up through the persistence layer, business layer, and presentation layer, which formats and displays it to the user.

In a layered architecture, the persistence layer and the database layer are distinct, with the persistence layer sitting between the business and database layers. The persistence layer is responsible for the logic of how to get data from the database, using technologies such as SQL. The database layer is where the actual data is stored.

Here’s a breakdown:

  • Persistence Layer: This layer contains the logic for interacting with the database, such as SQL statements. It acts as an intermediary, abstracting away the specifics of the database from the business layer. The persistence layer includes modules known as Data Access Objects (DAOs) that execute the SQL statements.
  • Database Layer: This layer is the actual data storage, where the database resides. This could be a relational database or a NoSQL database.

In the context of a Spring application, these layers are typically implemented using Spring Data JPA for the persistence layer, where it handles object-relational mapping between the Java objects in the application and the database. The database layer would be the actual database system the application is connecting to (e.g. PostgreSQL, MySQL, etc).

Layers in a spring web application

In a typical layered architecture, a Spring web application is composed of several layers, each with distinct responsibilities. These layers include the presentation, business, persistence, and database layers. The source also indicates that some applications combine the business and persistence layers.

Here’s how these layers are typically represented in a Spring web application:

  • Presentation Layer: This layer is responsible for handling user interface and browser communication logic. It doesn’t need to know how to get customer data, only how to display the information. In Spring, this layer is often composed of:
    • Controllers: These handle incoming web requests and direct them to the appropriate service for processing.
    • Views: These are templates (like HTML, Thymeleaf, or JSP) that render the data to the user.
    • UI Components: This includes the front-end code responsible for displaying data.
  • Business Layer: This layer executes specific business rules associated with a request. It gets data from the persistence layer, performs business logic against the data, and passes that information to the presentation layer. Components in the business layer deal only with business logic. In a Spring application, this layer is often implemented using:
    • Services: These classes contain the business logic, orchestrate calls to other services or DAOs (Data Access Objects), and implement the core business rules of the application.
    • Business Objects/Entities: These represent the data that the business logic operates on, as well as the methods for getting and setting data.
  • Persistence Layer: This layer is responsible for the logic of how to get data from the database. It acts as an intermediary, abstracting away the specifics of the database from the business layer. It includes modules that execute SQL statements. In Spring, this is typically implemented using:
    • Data Access Objects (DAOs) or Repositories: These components handle the database interactions and use technologies like SQL. Spring Data JPA is often used here to handle object-relational mapping [previous conversation]. These components can extend JpaRepository to inherit default methods for CRUD operations.
  • Database Layer: This layer is where the actual data is stored [previous conversation]. It could be a relational database or a NoSQL database [previous conversation]. Spring does not directly interact with this layer, instead going through the persistence layer.

The layers in a layered architecture can be either open or closed. A closed layer requires a request to pass through the layer directly below it to get to the next one. This concept facilitates layers of isolation so that changes in one layer generally don’t affect other layers. However, open layers allow requests to bypass them. For example, a shared services layer is often marked as open, allowing business logic to bypass it to get to the persistence layer.

The layered architecture is a common approach, particularly when teams are organized by technical domains. However, it’s important to consider potential drawbacks like the “architecture sinkhole anti-pattern,” where requests pass through multiple layers with minimal processing. This can be mitigated by making some layers open.

Conclusion

In this post, I’ve introduced you to the layered architecture.

Leave a Comment