Original address: Liang Guizhao’s blog

Blog address: blog.720ui.com

Welcome to reprint, reprint please indicate the author and source, thank you!

Layering is one of the most common architectural patterns in application systems. We will divide the system horizontally according to business responsibilities. MVC three-tier architecture is a very typical architecture mode, which is divided to plan the logical structure of the software system for development and maintenance. MVC: Model-view-controller, divided into Model layer, View layer, control layer. Separate pages from business logic to improve scalability and maintainability of applications. As shown in the figure.

As a matter of fact, the MVC three-tier architecture is just the guiding idea at the conceptual level, and we will divide the hierarchical structure into more details. For example, the traditional MVC pattern of the back end has blurred boundaries between the front and back ends. In general, front-end developers are responsible for writing the static pages of the project, including HTML pages, CSS styles and JavaScript interaction parts, and provide the server-side developers to write the business of the view layer. Some projects even let front-end developers directly complete the business development tasks of the view layer. The problem caused by such a development mode is that the division of labor of the front and back ends is not clear in the development process, and there is strong dependence on each other. The front-end developers need to care about the business of the server, and the server developers also need to depend on the progress of the front end. And with the addition of Android, IOS, PC and U3D clients, the development cost and maintenance cost of the program will increase exponentially. In order to improve the development efficiency and refine the responsibility, the need to separate the front and back ends is more and more important. The separation of front and back ends is that the server provides API interface and the front end calls AJAX to realize data interaction. As shown in the figure.

In addition, with the expansion of data storage capabilities (MySQL, Oracle, Redis, MongoDB, ElasticSearch, PostgreSQL, HBase, etc.) and the popularity and popularity of microservices, We often call third party platforms via RPC (Dubbo, HSF, Thrift, etc.) relying on many external interfaces or HTTP. Therefore, we need a finely divided code structure. In addition, a lot of times we don’t separate their responsibilities during development. For example, in the code structure, we put a lot of logical business in the Controller layer, and only use Service as a way to pass through data. Actually, that’s not true. Coincidentally, we also find that some projects invoke remote services in the Dao layer, while others conduct such operations in the Service layer or Controller layer. Due to the different habits of students in different r&d projects, or cutting corners, the development code styles are completely different, and the code hierarchy is chaotic.

To sum up, the MVC three-tier architecture is just the guiding idea at the conceptual level, and we will divide the hierarchical structure into more details. Now, let’s go deep into “how to design code layering reasonably, on the design of code layering”. In my opinion, a reasonable code layering would look like this. As shown in the figure.

Data persistence layer

The business logic layer, then, is responsible for interacting with the __ data persistence layer __, aggregating operations from multiple data sources, and providing combinational reuse capabilities. In addition, it is the processing layer for business common capabilities, including caching schemes, message listening (MQ), scheduled tasks, and so on. In addition, we want to put as much business processing as possible in __ business logic layer __, including parameter verification, data conversion, exception handling, and so on, rather than in Controller.

In my view, the request processing layer has three pieces of capability, one is rendering through template engine, such as FreeMarket, Velocity page rendering, and HTTP interface encapsulated through the Controller layer RESTful API. If RPC services such as Dubbo, HSF, and Thrift are used in the project, we also need to provide the appropriate services for upstream business parties to use, which are implemented through services and exposed as RPC interfaces. In this case, the name of a Service is relative. Generally, the interface is provided through the Client, and the specific Service logic is implemented through the Service.

Now that we know the logical structure, I think a clearer physical code structure should look something like this.

So, can we call across hierarchies? In my opinion, we need to prohibit calls across layers, because each layer has its own responsibility and is transparent to the upper layer. Like the OSI 7-layer protocol model and TCP/IP 4-layer protocol model, the overall hierarchy is only clear if the responsibility is restricted within its own boundaries. So for peer calls, I think it is allowed at the business logic layer, but pay special attention to the generation of circular calls.

Now let’s take a lateral look at several domain models: VO, BO, DO, and DTO. This concept was introduced by the Ali Code specification, which is very complex in its business, in order to better conduct domain modeling and model isolation. Among them, DO (Data Object) corresponds to the database table structure one by one, and transmits Data source objects up through DAO layer. Data Transfer Object (DTO) is a remote call Object, which is the domain model provided by RPC service. Note that the SERIalization of DTO must be guaranteed by implementing the Serializable interface and showing the serialVersionUID, otherwise the deserialization will fail if the serialVersionUID is changed during deserialization. In fact, the only difference between DO and DTO is that one is the domain model for local data sources and the other is the serialized domain model for remote services. For the Business Object (BO), it is an Object that encapsulates Business logic at the Business logic layer. In general, it is a composite Object that aggregates multiple data sources. VO (View Object) is usually the Object transferred by the request processing layer, and it is usually a JSON Object after being transformed by the Spring framework. For example, you might need to address the loss of accuracy of Long data (which can occur when Long is larger than 17 bits if passed directly to the Web), You can encapsulate it as a string at the Controller layer when you automatically convert the returned data to JSON via @responseBody.

To summarize, the idea of layering, cutting the system horizontally, dividing it according to business responsibilities. The purpose of division is to plan the logical structure of the software system for development and maintenance. However, the evolution of microservices and the coding habits of different developers often lead to incomplete code layering leading to the introduction of “bad taste”. The author tries to put forward a new idea of code layering to avoid and standardize this layering structure.

If you have different ideas and interests, please join us on wechat to discuss and communicate with us

(End, reprint please indicate the author and source.)

More wonderful articles, all in the “server-side thinking”!