Java code layering

一下是一个典型的java微服务项目的代码调用结构,分层次的目的在于解耦合内聚变化减少重复代码

为了达到解开的目的我们会采用Pojos来对每层之间的输入输出进行隔离,以期望,如,对视图的改动,格式化,等等不会对业务产生太大影响,为此我们会产生以下对象:

  • VO(View Object) 视图对象,他用于展示业务数据的封装格式,常常和视图一一对应。

  • QMO(Query Model Object) 查询模型对象。顾名思义,用于查询结构的封装载体

  • DTO(Data Transfer Object) DTO对象,即一个数据载体的封装格式。

  • DO(Domain Object)领域模型对象,也叫Entity实体对象,这里是我们对业务的模型的抽象模型,映射现实业务中的实体。

  • PO(Persistent Object) PO对象,即持久化对象,用户解耦存储和业务直接的关系。实际开发中有了ORM之后,可直接用DO/Entity代替。和存储的(表结构,Document)等格式一一对应。

有了这些对象的基本概念我们就可以对代码结构进行分层,完整的结构如图:

我们从上而下,可以看到第一层,这一层主要是我们的Controller,主要的职责是负责解析HTTP协议并把协议转换为我们所需要的DTO,QueryModel对象(这里一般springmvc框架帮我们搞定),拿到之后调用对应的业务方法,或者视图组件返回对应的业务结果或VO。

第二层是VOComponent,VO组件工厂,这里处理VO的组装工作,这里接受Controller传递过来的QMO对象,并调用对应的业务方法,拿到业务方法返回的PO/Entity,根据需求对数据进行相应的格式化,脱敏,等等展示相关的处理,并返回具体的VO给Controller。

第三层是我们的事物脚本层(Service)这里负责两个事儿件事儿:

  1. 接受Controller传过来的DTO对象和VoComponent传递过来的QMO对象,完成业务逻辑(组合复用的业务组件),构造出DO/Entity对象,调用ORM持久化。
  2. 事务的边界,负责控制事务的开启,提交回滚等,在spring中一般采用AOP的方式统一进行控制。

第四层是BizComponent,业务组件层,这里会存放公有的业务方法,比如说,构造财务单据,收益发放,等等一些需要在多个业务逻辑中使用的共有方法。这里一般接受Service的DTO输入,并构造出DO/Entity对象,

比较常见的java仓库构建模式是已系统为单位的多module的maven项目

1
2
3
4
5
6
xxx-parent.git
#典型的结构如下
xxx-parent
xxx-service
yyy-service
ddd-service

这种方式下所有的代码都在一个仓库中存在以下问题

  1. 代码权限无法控制。任何一个开发都能拉取全部代码。
  2. 由于只有一个仓库,随着业务越来越多,会导致模块boom,编译困难,排查困难。
  3. 过度复杂,当模块增加到几十上百个时,没一个开发都需要面对这所有代码,特别的复杂和混乱。
  4. CI/CD不友好,提交任意一个module的代码修改,不能自动化的只部署相对应修改部分代码,难以做持续集成和持续交付。
  5. 干扰性较大,容易发生改错地方的情况,特别是未付模特别多的时候。
  6. 大家都吃一个大锅饭,很容易导致各种GIT冲突。
  7. 这一切的最终结果就是带来效率比较低。不能难以推进自动化。

所以推荐一下分仓库的方式为每一个服务建立独立的仓库。

1
2
3
4
5
6
7
base.git 

xxx-service.git

yyy-service.git

ddd-service.git

基于这种方式的好处

  1. 每一个git仓库只存一个微服务的业务代码,很干净和清爽了。
  2. 代码权限控制起来很容易,每个人都能专注于自己的业务仓库,不会有其他的干扰。
  3. CI/CD友好,很轻松的完成Devops自动化工具链,轻松搞定持续交付和持续集成。
  4. 关注的代码量较少,减少BUG的产生。

推荐文章