java 业务分层设计

1,464 阅读4分钟

前言

  1. 在业务开发过程中,普遍的分层为 controller、service、serviceImpl、mapper或dao、entity,等几层。但是在业务复杂度相对比较高的情况下。serviceImpl层中的逻辑会非常复杂,并且冗长。
  2. 所以在参考了其他的分层设计,并且根据自己的经验。对分层与职责进一步细化,项目与模块,根据实际情况进行取舍。
  3. 公共组件和框架组件,这里不分析。

项目结构

XXX项目
│
├─doc    项目文档
│  │ 
│  └─sql    sql文件,可以按照日期进一步区分。
│     │
│     └─ yyyy-MM-dd-功能.sql
│  
├─xxx-业务模块-api    对外接口(com.公司.项目.业务.模块.api)
│  │
│  ├─dto    对外实体包
│  │  │
│  │  ├─in    dto入参(类名:XxxInDTO)
│  │  │
│  │  └─out    dto出参(类名:XxxOutDTO)
│  │
│  ├─feign    feign接口(接口类名:XxxFeign)
│  │
│  └─hystrix    feign接口熔断返回实现(类名:XxxFallback)
│
├─xxx-业务模块-service    业务服务(com.公司.项目.业务.模块.service)
│  │
│  ├─provider    服务提供者,对应feign接口的实现(类名:XxxProvider)
│  │
│  ├─controller    控制层(类名:XxxController)
│  │
│  ├─service    服务层(类名:XxxService)
│  │  │
│  │  ├─impl    服务实现(类名:XxxServiceImpl)
│  │  │
│  │  ├─helper    服务帮助者(类名:XxxHelper)
│  │  │
│  │  └─checker    服务校验者(类名:XxxChecker)
│  │
│  ├─mapper    持久层(类名:XxxMapper)
│  │
│  ├─domain    实体
│  │  │
│  │  ├─converter    实体转换(类名:XxxConverter)
│  │  │
│  │  ├─bo    当前服务之间传输对象
│  │  │  │
│  │  │  ├─in    入参(类名:XxxInBO)
│  │  │  │
│  │  │  └─out    出参(类名:XxxOutBO)
│  │  │ 
│  │  ├─vo    显示层传递过来的参数(类名:XxxVO,表单提交与详情,共用一个)
│  │  │  │
│  │  │  ├─in    入参(类名:XxxInVO、XxxQueryVO)
│  │  │  │
│  │  │  └─out    出参(类名:XxxOutVO)
│  │  │
│  │  └─entity    数据库实体(类名:XxxEntity、XxxDO)
│  │  
│  ├─remote    远程调用(类名:XxxRemote)
│  │  │
│  │  ├─converter    远程对象转换器(类名:XxxRConverter)
│  │  │
│  │  ├─rbo   远程入参和出参对象(类名:XxxRBO)
│  │  │
│  │  └─helper    帮助者(类名:XxxRHelper)
│  │
│  └─util    静态工具类(类名:XxxUtil)

结构说明

层名描述
feign提供服务接口,给外部服务调用。如果有条件,通过接口的 default 关键字,返回处理后的数据。
hystrixfeign异常时,返回处理方法。
dto.infeign接口的入参
dto.outfeign接口的出参
providerfeign接口的实现,提供 feign 对应的服务
controller正常服务的控制层。接收 domain.VO 中的对象
service服务接口。如果接口太多,可以试着拆分。简单拆成 ReadService 和 WriteService 两个服务,可以接收所有的实体参数,并且使用 default 关键字,在接口层进行转换,不用额外的实现。
service.impl服务实现。与 service 对应,只能引用当前 serivce 实体的 mapper,不能引用其他实体 mapper。如果需要,必须通过引入其他 service 来进行处理。如果逻辑过长,可以使用专用的 hepler 进行抽取封装,提高可读性。
service.checker服务校验者。将服务的一些复杂的校验规则,封装到该类中,可以提供给其他服务的 helper 使用。
service.helper服务帮助者。主要功能是将 serviceImpl 中的复杂逻辑进行封装。使得 serviceImpl 简化。并且对 checker进行组合,将多个校验规则进行整合。
mapper持久层。没啥注意点,也可以改名为 dao
domain实体
domain.entity与数据库表结构对应,不允许添加额外的信息
domain.bo当前工程中,service 之间调用的传参。in入参,out出参。
domain.vo显示层的入参和出参。如果入参和出参相同,则直接放在 vo 目录下,命名为 Xxx[修饰词]VO。
domain.converter实体转换器。service 调用 converter 对 实体进行转换。
remote远程调用。如果 service 需要调用外部项目的接口,则不能在 serviceImpl 中直接引用,必须通过 remote 层操作。目的是为了减少 serviceImpl 的逻辑,与异常操作。如果想要改成同步和异步调用,也方便。
remote.rbo远程调用实体与本工程实体的映射。保证如果远程对象修改,本工程不需要改动很多内容。
remote.converter远程调用实体与本工程实体转换器。目的是避免字段修改,导致需要大概逻辑。
remote.helper如果逻辑不是很复杂,则可以不需要。
util静态工具类

总结

目前的分层对于复杂的业务场景基本能够适应。也可做进一步的扩展。比如说 相同类型的操作,可以再次归纳成一层。 如:有很多表都有历史表备份、还原、复制数据、复制远程数据,等相同操作。就可以再次抽取 service.his、service.his.impl、mapper.his、domain.his 等层进行进一步区分。 分层的目的是为了让工程看起来更加规范,通过层名就能够知道职责,快速定位问题,解耦和复用。

后续补充备份还原业务框架