DO、DTO、VO、POJO使用场景

总结:

分层领域模型规约:

  • DO( Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
  • DTO( Data Transfer Object):数据传输对象,Service或Manager向外传输的对象。
  • BO( Business Object):业务对象。 由Service层输出的封装业务逻辑的对象。
  • AO( Application Object):应用对象。 在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
  • VO( View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
  • POJO( Plain Ordinary Java Object):在本手册中, POJO专指只有setter/getter/toString的简单类,包括DO/DTO/BO/VO等。
  • Query:数据查询对象,各层接收上层的查询请求。 注意超过2个参数的查询封装,禁止使用Map类来传输。

领域模型命名规约:

  • 数据对象:xxxDO,xxx即为数据表名。
  • 数据传输对象:xxxDTO,xxx为业务领域相关的名称。
  • 展示对象:xxxVO,xxx一般为网页名称。
  • POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。

详细介绍(可只看上面,下面只是介绍)

对于项目而言, 我们一般会有DAO->Service->Controller分层设计, 这些层次体现了每层的作用, 而层次之间的数据传递对象设计很少被提及, 下面是一个相对完整的数据转换过程:
Table层–(DO对象)–>DAO层–(DO对象)–>Service层–(DTO对象)–>Controller层–(VO对象)–>Web Template层

DO(domain object) 领域对象, 也有一种叫法是 entity object, 个人不推荐使用 entity object这个叫法, 因为Relationship 表也可以有DO 类.

  1. 一般DO类和数据表是一一对应, 属性和字段也是一一对应的.
  2. 对于 relationship 表, 一般也需要有一个对应的 DO 类.
  3. DO 类中不应该包含复杂的逻辑, 仅仅是一些简单的 setter() 和 getter() 方法.
  4. 比如 user 表有一个 deptId 字段, user entity 类必须有一个 deptId 属性, 不推荐有一个对应的 dept Entity 对象, 当然更不应该直接包含 dept entity 对象的属性, 比如 deptName 等.
  5. 多个 DO 类之间的关系和数据模型一样, 是满足第三范式.
  6. DO类名: 以DO作为后缀, 或者不加DO这样的后缀.

DTO(Data Transfer Object) 数据传输对象:

  1. 用于"跨进程或远程"传输, 对象的序列化/反序列化的网络开销较大, 这时就需要加入 DTO 对象, 典型的使用场景是用来封装Rest API接口. 如果是一个单体应用, 专门维护一套DTO类, 成本和收益相比, 引入DTO意义就不大了.
  2. DTO 是一个贫血对象, 它不应包含"业务"处理逻辑, 主要是一些属性和getter和setter访问器, 也可包含一些属性重组逻辑.
  3. 多个 DTO 类之间的关系一般不再满足第三范式, 而是反范式.
  4. DTO类名: 应该以DTO作为后缀.
  5. 用于解耦实体对象的存储层和上层, 这包含下面的好处:
    (1): 隐藏部分底层表的属性, 以减少网络传输的代价.
    (2): 在存储层和上层增加一个隔离, 屏蔽相互之间的影响.
    (3): 用来可封装多个DTO对象, 比如user DTO对象可以包含一个Dept DTO对象; 或者将Dept DTO某些常用属性直接flatten到User DTO对象上, 方便上层的使用. 所以, 一般情况下DTO类的数量要比DO类要少.
    (4): 如果没有DTO, 很多时候 Controller 层不得不直接最低层的 Entity 类, 跨层数据对象依赖将使得分层设计大打折扣.

VO(View Object/Value object)视图对象:
专门用于展现层(比如页面展现等).
对于一般的项目, VO 和 DTO 属性基本一致, 没有必要再维护一套VO类.
在前后端分离的大背景下, 即使是大型项目, 也没有必要再维护一套VO类.

Pojo(plain old java object) 普通java对象:
上述的DO/DTO/VO对象都属于Pojo对象. 阿里巴巴规范中有如下要求:

  1. Pojo 类属性必须使用包装数据类型, 而不是基本数据类型, 理由是: 数据库中由可能是null值, 如果使用基本类型, 由可能导致自动拆箱异常.
  2. 不能为任何属性设定默认值. 理由是: 强制使用者在使用时显式赋值, 任何NPE问题都应由使用者来保证.
  3. Pojo 类都必须实现 toString() 方法, 可以使用 IDE 的 source/generate toString() 功能
  4. Pojo 类都必须实现 Serializable 接口.

下图能形象展现 DO 类和 DTO 类的区别:
在这里插入图片描述

下图以基于角色的权限管理模块为例, 展现了 table/DO对象/DAO层/Service层 对应关系:
(1) table 是采用范式建模, 共三个实体表, 两个关系表.
(2) pojo和table直接对应,
(3) 在Dao层重点关注实体的操作, 所以就只有三个dao对象, 关系表的维护退化到实体操作中.
(4) 在service层, 是面向顶层使用, 重点考虑的是使用如何方便, 一般也都和Dao的类数量一致.

在这里插入图片描述

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值