As we all know, the current spring framework has become the de facto standard for building enterprise Java applications, and many enterprise projects are built on spring projects and their sub-projects, especially Java Web Projects, many of which use spring and follow the web, Service, DAO's layered principle, the lower layer provides services to the upper layer; but Petri Kainulainen, in its blog, points out the biggest flaws in many of the spring Web applications, read on to see if the issues mentioned in the article are also in your project.
Developers building apps using the Spring Framework are happy to talk about the benefits of dependency injection. Unfortunately, many of them do not make good use of their advantages in their applications, such as the single principle of responsibility and the principle of separation of concerns. If you take a closer look at spring-based Web applications, you will find that many of them are implemented using the following common and erroneous design principles:
- A domain model object is just the data that is used to store the app. In other words, the domain model uses this anti-pattern of anemia models.
- The business logic is located in the service layer and manages the data for the domain object.
- In the service layer, each entity that is applied corresponds to a service class.
But the question is: if this is a common practice, why is it wrong? Here's a little bit of detail.
Stereotypes are hard to change
The reason the Spring Web app looks like this is because it's a long-standing practice, and it's hard to change stereotypes, especially when advanced developers or software architects force developers to do so. The problem is that these people are very good at defending their views. One of the arguments they like is that applications should follow the principle of separation of concerns, because it is divided into several levels, each with its own specific responsibilities.
A typical spring Web application will have the following layers:
- Web tier: Takes care of the user's input and returns the correct response to the user. The web layer communicates only with the service layer.
- Service layer: As a transaction boundary. It is also responsible for authorizing and incorporating the business logic of the application. The service layer manages the domain object model and communicates with other services and storage tiers.
- Storage/Data Access layer: responsible for communicating with the data store being used.
The definition of concern separation principle is this: separation of concerns (SOC) is a design principle that divides computer programs into different parts, so that each part has a separate focus. While a typical spring Web application follows this principle to some extent, the reality is that the application has a whole service layer that contains too many responsibilities. More specifically, the service layer has two main problems:
First, the business logic of the application comes from the service layer.
This is a problem because the business logic is scattered over the service layer. If you need to see how a business rule is implemented, we need to find it first, which is not a very easy thing to do. In addition, if more than one service class requires the same business rules, it is likely that the developer will replicate this business rule from one service to another, which can lead to a maintenance nightmare.
Second, each domain model class has a service class in the service layer.
This violates the single principle of responsibility: the single responsibility principle indicates that each class should have only one responsibility, which should be fully encapsulated by this class. All its services should be aligned with this responsibility.
The service class has a lot of dependencies and a lot of cyclic dependencies. A typical spring Web application's service layer does not contain loosely coupled services that have only one responsibility, which is more like a collection of tightly coupled, large numbers of services. This makes it difficult to understand, maintain, and reuse. Looks a bit harsh, but the service layer is often one of the most problematic aspects of spring Web applications. Fortunately, there is hope for us.
Overthrow
The present situation is not good, but it is not entirely hopeless. Let's take a look at how to break the old habits.
First, we need to move the application's business logic from the service layer to the domain model class.
Why do we have to do this and take a look at the following example:
Let's say I'm a service class, you're a domain model object. If I told you to jump off the roof, would you refuse?
Moving the business logic of the service layer into the domain model class has the following 3 benefits:
- The responsibility for dividing the code in a reasonable manner. The service layer is responsible for the applied logic, while the domain model class is responsible for the business logic.
- The application's business logic will only be in one place. If you need to verify how a particular business rule is implemented, we always know where to look.
- The source code for the service layer will become neater and will not contain any copy-and-paste.
Second, we need to divide the entity-specific services into smaller services, with only one target per service.
For example, if an application has a service class that provides CRUD operations for people and operations related to user accounts, then we should divide it into two separate service classes:
- A crud operation for the 1th service provider.
- The 2nd service provides actions related to user accounts.
There are 3 benefits to doing so:
- Each service class has a reasonable set of responsibilities.
- Each service class will have fewer dependencies, which means they are no longer tightly coupled behemoths. They are more compact and loosely coupled components.
- Service classes are easier to understand, maintain, and reuse.
These two simple steps help us to clean up the architecture of the application and improve the productivity and happiness of the developer. Now, we want to know if all of this is necessary, then when will the problem be solved?
Sometimes life is black and white.
I often hear people say that we should not focus too much on "architecture" because our applications are small and simple. Although this argument is correct, we have to remember that a very small project at the beginning will eventually become very big. If this is not the case, then we will be in great trouble in the event of a situation. Sailing in uncharted waters is not a good idea, but we have to know that the Titanic sailed on the familiar route when it hit the iceberg. This kind of thing also happens in our application. When things become uncontrollable, we must have the courage to say no.
If you intend to change, then I recommend you read the Olivier Gierke wrote "Whoops! Where did my architecture "(or watch his lecture on SPRINGONE2GX on the project). But please note that the power of habit is still very strong.
The biggest flaw in Spring Web Apps