1. 为什么要做代码分层
➢ 使代码更加易读易理解;
➢ 实现责任分离;
➢ 实现组件复用;
➢ 制定统一标准;
➢ 便于代码维护及扩展;
2.传统的代码分层
传统或大多数人理解的代码分层就是controller,service,mapper三层。
controller层:主要是对访问控制进行转发,各类基本参数校验,或者顶层异常处理等。
service层:实现相对具体的业务逻辑服务层。
mapper层:数据访问层,与底层数据库进行数据交互。
虽然传统的三层分层已经很明了,但是实际开发中很多人依然并没有把他们职责划分开,
很多开发人员将大量的业务代码写到controller层中,service层只起到透传mapper层的作用,
这就造成大量代码无法复用,层级关系混乱,对后续代码的维护和扩展非常头痛。
3. 阿里的代码分层规范
开放接口层 :可直接封装 Service 方法暴露成 RPC 接口;通过 Web 封装成 http 接口;进行 网关安全控制、流量控制等。
终端显示层 :各个端的模板渲染并执行显示的层。当前主要是 velocity 渲染,JS 渲染, JSP 渲染,移动端展示等。
Web 层 :主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
Service 层 :相对具体的业务逻辑服务层。
Manager 层 :通用业务处理层,它有如下特征:
1. 对第三方平台封装的层,预处理返回结果及转化异常信息;
2. 对Service层通用能力的下沉,如缓存方案、中间件通用处理;
3. 与DAO层交互,对多个DAO的组合复用。
DAO 层 :数据访问层,与底层 MySQL、Oracle、Hbase 进行数据交互。
4. 实际开发中代码分层
对于很多简单业务而言,Manager 层 是不存在的,但如果存在上述情况:
需要用到缓存、中间件、调用其他服务、调用其他mapper,最好还是创建 Manager 层,
在其中去处理,有 Manager 层就杜绝Service调用Service的情况,
一方面便于他人调用,一方面可以防止出现循环依赖问题。
4. 分层领域
4.1 在阿里编码规约中的领域模型:
POJO(Plain Ordinary Java Object):简单Java对象,它没有任何限制和特定的约定,是一个普通的Java对象
(BO/VO/PO/DO等一系列对象的总称,通常不建议使用它命名)。
DTO(Data Transfer Object):数据传输对象,它是一个数据传输结构
,通常用于不同进程间的数据传输,在不同层之间传递数据的对象。
其含义较为广泛,接口的输入输出都可以视作是DTO,如 XXRequestDTO 和 XXResponseDTO,
通常每个接口都会定义其对应 XXRequestDTO 和 XXResponseDTO。
PO/DO(persistence object/data object):持久化对象,通常指ORM(对象关系映射)中映射的数据库表对应的实体类。
BO(business object):业务对象,是应用程序中业务逻辑的实现。
通常是实体,或者是聚合根,包含多个实体或值对象,内部实现业务逻辑。
像Controller,Service,Mapper等也可被称为业务对象(BO)。
VO(value object):值对象,通常用于业务层之间的数据传递,仅仅包含自身的数据。
与实体的区别是,没有唯一标识,无生命周期,内部值是不变的。某种程度上与 DTO 作用一致。
VO(View Object): 显示层对象,Web向模板渲染引擎层传输的对象。
QO(Query Object):查询对象,它主要用于定义查询条件和规则,用于接收前端传递的查询条件参数。
ENTITY:实体对象,是一个与业务相关的对象,通常是与应用程序领域模型相关的对象。
Param:表示请求参数,用于接收前端传递的参数
Command:表示命令,用于接收前端传递的命令参数
每一个层基本都自己对应的领域模型,这样就导致了在一次请求中一个对象可能会出现3次甚至4次转换,
当返回的时候同样也会出现3-4次转换,这样有可能一次完整的 请求——返回 会出现很多次对象转换。
如果在开发中这么做,不仅会浪费大量的时间精力,还会出现大量冗余的代码,得不偿失。
4.1 实际开发中的领域模型:
在实际开发中,个人觉得选择 VO(value object)或者 DTO(Data Transfer Object) + ENTITY 是比较折中的选择。
ReqVO:输入参数接受对象
RepVO:输出数据对象
Entity:实体对象
R:统一封装的 RepVO 输出对象
5. 实际开发中,不管是代码的分层还是领域模型的设计其实都不会影响程序功能的实现,因为开发习惯的不同,对于哪种分层结构更好,选择那些领域模型也是见仁见智,但不可否认的是,优秀的分层结构、职责分明的领域模型会让代码的逻辑更加清晰,后续维护扩展更加容易。