Code Layering Best Practices for Java Web Applications.

Code layering should be familiar to any Java web developer. A good hierarchical division can not only make the code structure clearer, but also make the project division clearer, greatly improve readability, and be more conducive to later maintenance and upgrades.

From another point of view, a good code layered architecture should be able to well match the single responsibility principle. In this way, the dependencies between layers can be reduced, and the logic of each layer can be reused to the greatest extent. This article will introduce how the code of the Java Web project should be layered.

Three-tier architecture

In software architecture design, the layered structure is the most common and the most important one. The hierarchical structure recommended by Microsoft is generally divided into three layers, from bottom to top: data access layer, business logic layer (also called domain layer), and presentation layer. These are also three layers in the three-tier architecture that is important in the Java Web. The purpose of distinguishing layers is the idea of ​​"high cohesion and low coupling".

The so-called three-tier architecture is a "middle layer", also called the component layer, between the client and the database. The three-tier system mentioned here does not refer to the physical three-tier system. It is not simply placing three machines or a three-tier architecture. It is not only a B/S application that is a three-tier architecture. The three-tier system refers to the logical The three layers, that is, the three layers are placed on one machine.

data access layer

It is mainly the operation layer of non-original data (database or text file, etc.), rather than the original data, that is, the operation of the database, not the data, specifically for the business logic layer or presentation layer. data service.

business logic layer

It is mainly for the operation of specific problems, and it can also be understood as the operation of the data layer and the processing of data business logic. If the data layer is a building block, then the logic layer is the construction of these building blocks.

interface layer

Mainly represents the WEB method. If the logic layer is quite powerful and complete, no matter how the presentation layer is defined and changed, the logic layer can provide services perfectly.

The difference between three-tier architecture and MVC

MVC (Model-View-View-Controller Controller) is an architectural pattern that can be used to create a distinction between domain objects and UI presentation layer objects.

MVC

The same is at the architectural level, the same thing is that they have a presentation layer, but they are different in the other two layers.

在三层架构中没有定义Controller的概念。这是最不同的地方。而MVC也没有把业务的逻辑访问看成两个层,这是采用三层架构或MVC搭建程序最主要的区别。

3

更加细致的分层

随着网站的用户量的不断提升,系统架构也在不断的调整。有时候,随着业务越来越复杂,有时候三层架构好像不够用了。比如,我们的应用除了要给用户提供页面访问以外,还需要提供一些开放接口,供外部系统调用。这个接口既不属于界面层,也不应该属于业务逻辑层,因为他还可能包含一些和业务逻辑无关的处理,如权限控制、流量控制等。

还有,随着微服务的盛行,我们应用中可能要依赖很多外部接口或第三方平台。这部分代码放下业务逻辑层和数据访问层也都不合适。

所以,渐渐的,在三层架构的基础上,系统架构的分层变得更加复杂了。也正是因为复杂,就非常考验架构设计能力,因为层次划分的不好,很可能会影响后面的开发,给代码维护带来很大的困难。

下图,是阿里巴巴(参考《阿里巴巴Java开发手册》)提倡的应用分层结构:

ceng

开放接口层

可直接封装 Service 方法暴露成 RPC 接口;通过 Web 封装成 http 接口;进行网关安全控制、流量控制等。

终端显示层

各个端的模板渲染并执行显示的层。当前主要是 velocity 渲染,JS 渲染,JSP 渲染,移动端展示等。

Web 层

主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。

Service 层

相对具体的业务逻辑服务层。

Manager 层

通用业务处理层,它有如下特征: 1) 对第三方平台封装的层,预处理返回结果及转化异常信息; 2) 对 Service 层通用能力的下沉,如缓存方案、中间件通用处理; 3) 与 DAO 层交互,对多个 DAO 的组合复用。

DAO 层

数据访问层,与底层 MySQL、Oracle、Hbase 等进行数据交互。

外部接口或第三方平台

包括其它部门 RPC 开放接口,基础平台,其它公司的 HTTP 接口。

事务处理

在了解了分层之后,我们再来看一下写Java Web代码的时候,大家比较关心的一个问题,那就是涉及到数据库操作的时候,事务处理应该在哪一层控制呢?

关于这个问题,仁者见仁,智者见智。作者认为,事务处理应该放在Service层和Manager层。

DAO层不应该有事务,应该只是很纯的 CRUD 等比较通用的数据访问方法。一个DAO应该只处理和自己相关的操作,不要有任何组合。组合的事情交给上层。

Service层和Manager层一般会组合多个DAO的CRUD操作,例如:在注册一个用户的时候需要往日志表里 INSERT 日志,那么就在 Service 层构造事务,在该事务中调用 Dao 层的 User.Insert () 与 Log.Insert ()。

异常处理

异常处理是Java中比较重要的一个话题,在《Effective Java》中有很多关于异常处理的最佳实践,这里不详细介绍了,本文主要简单说一下在应用代码分层之后,各个层次之间的异常应该如何处理,是自己捕获,还是向上一层抛出。

首先,每一层都是可能发生异常的。由于每一层的职责都不通,处理方式也可能有差别。

DAO层

在 DAO 层,产生的异常类型可能有很多,可能是SQL相关的异常,也可能是数据库连接相关的异常。

这一层的处理方式可以简单一点,直接try-catch(Exception),然后封装成DAOException抛给上一层。这一层一般不需要打印日志,交给Service或者Manager层来打印。

try{
    CRUD
}catch(Exception e){
    throw new DAOException(e);
}

Manager/Service

首先,对于DAO层抛上来的异常一定要捕获的,并且记录日志打印现场。

但是值得注意的是,如果是需要事务控制的方法,要注意捕获到异常之后再向上抛一个新的异常,如 TransactionRolledbackException,否则事务无法回滚。

The exceptions that occur in these two layers can be decided according to the situation whether to continue to throw upwards or deal with them by themselves. If it is an exception that can be handled by itself, capture it, log it, and then return it to the upper layer through ErrorCode and other methods. If it is an exception that you can't handle or don't know how to handle, throw it directly to the upper layer to handle it.

Web

First of all, it is clear that the Web layer should not throw exceptions, because once this layer throws an exception, it may cause users to jump to unfriendly error pages or even see error messages.

If you realize that this exception will cause the page to fail to render properly, you should jump directly to a friendly error page with an easy-to-understand error message.

open interface layer

This layer, like the Web layer, cannot throw exceptions. It is generally fed back to the external caller through ErrorCode and ErrorMessage.

At this layer, you must handle all exceptions yourself, define ErrorCode, and record logs to facilitate future troubleshooting.

Summarize

This article mainly introduces the code layering scheme in Java Web projects. After layering, each layer can be more focused and decoupled. And briefly introduced the logic of transaction processing and exception handling after layering.



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326017912&siteId=291194637