Layered Architecture Is Good

Darek, the guy who reviews almost all Tidy Java posts before they are published, suggested that I could do a series on implementing different architectural styles — their pros, cons, etc. I decided to give it a try, and here comes the first one – Layered Architecture. To avoid misunderstandings, let me note that I will present the Layered Architecture as I was taught/learned, which might be different than the one you know or some sources present. Enjoy!

What Is Layered Architecture?

A Layered Architecture, as I understand it, is the organization of the project structure into four main categories: presentation, application, domain, and infrastructure. Each of the layers contains objects related to the particular concern it represents.

There are two important rules for a classical Layered Architecture to be correctly implemented:

  1. All the dependencies go in one direction, from presentation to infrastructure. (Well, handling persistence and domain are a bit tricky because the infrastructure layer often saves domain objects directly, so it actually knows about the classes in the domain)
  2. No logic related to one layer’s concern should be placed in another layer. For instance, no domain logic or database queries should be done in the UI.

Image title

The Essence of Layered Architecture

Architecture is kind of an overloaded term, so we should probably dig deeper into what the term really means in the context of layers. The main idea behind Layered Architecture is a separation of concerns – as we said already, we want to avoid mixing domain or database code with the UI stuff, etc. The actual idea of separating a project into layers suggests that this separation of concerns should be achieved by source code organization. This means that apart from some guidance to what concerns we should separate, the Layered Architecture tells us nothing else about the design and implementation of the project. This implies that we should complement it with some other architectural processes, such as some upfront design, daily design sessions, or even full-blown Domain-Driven Design. Whichever option we choose doesn’t matter, at least for the sake of layering, but we need to remember: Layered Architecture gives us nothing apart from a guideline on how to organize the source code.

Implementing Layered Architecture

Equipped with the knowledge of the layers to create, the relationships between them and the essence of the architecture, we are ready to implement it. As most of you probably expect, we will slice the system into layers by creating a separate package for each of them. When it comes to applying the dependency and separation rules, things are not so obvious. One could try putting each layer in a separate Maven module, but then capturing the weird relationship between domain and persistence would not be easy. I usually stick with packages and use common sense along with code reviews to make sure that none of the rules are broken.

Layering Spring Pet Clinic

Since I didn’t want to force you to learn a new project just to grasp a simple idea, I decided to use a project that all Java developers should be familiar with – Spring Pet Clinic. At the time of writing this post, the project uses some weird packaging, that is probably supposed to be more domain-oriented. Let’s see how the two ways of code organization stack against each other:

Image title

I’ll leave the interpretation to you. One thing that I did not expect, which is now clear, is that there were no application services in the project – almost everything is done in the controllers! I haven’t seen it until I actually moved the classes to their best-fit layer packages.

Benefits of a Layered Architecture

Although some of you might still not believe it, Layered Architecture has some benefits, including:

Drawbacks of a Layered Architecture

And, of course, Layered Architecture is not perfect. Some of its cons include:

When to Apply Layered Architecture

At first, I wanted to write some cases when I use Layered Architecture myself, but I think we could use a more methodical approach based on its pros and cons:

Summary

As you can see, a Layered Architecture has its bright and dark sides. To me, its simplicity and consistency make it a good fit for microservices without too much serious business logic. One could question if such microservices should exist in the first place, but the realities of factoring big monoliths often make them a lesser evil. The most important lesson that you should take away from this article is: Layered Architecture is about organizing code for a good separation of concerns and nothing else, really.

 

 

 

 

Top