初入 Java ,看不懂 各种奇奇怪怪的 PO、VO、DTO、BO、**O…求一份攻略

2023-11-16 06:27:04 +08:00
 mangojiji
一大堆疑惑:

入参时,Controller 接收哪个 O ?
Service 接收和 Mybatis 接收哪个 O ?

Mybatis 返回的可能是 PO (比如 getById 或者 selectByPrimaryKey),但也可能是自定义的 POJO 吧(比如一条复杂 Join 的结果),在这类情况下,Mybatis 返回的这些对象属于什么 O ?这些对象能被 Service 直接返回吗?

Service 应该返回什么 O 给 Controller ?

BO 又是个啥,看了不少资料愣是没整明白。

DTO 在什么时候用,有说层之间入参和输出的,也有说调用其它系统的,总之乱七八糟。。。

PS:项目没有使用 DDD ,是传统 SpringMVC+Mybatis 三层的设计。主要原因是我不懂 DDD…能力有限

最好能够配合示例代码或者伪代码,谢谢大佬们。
11943 次点击
所在节点    Java
94 条回复
cnhongwei
2023-11-16 09:36:55 +08:00
我是能用 Entity 就用 Entity ,不能用 Entity ,全部都叫 VO ,从前传到后,再从后传到前,因为这个名称我看着顺眼一些。
ocean1477
2023-11-16 09:39:04 +08:00
一般我自己习惯 controller 的 save/update 用 DTO 接收,然后透传到 service 那边在 service 做 DTO -> Entity/DO 转换,返回值给 VO 。这里要在 service 里面做 DO 到 VO 的转换,需要给到前端对象里面的自增 id ,可以跟下面 query 返回值的转换用一套,不给数据库层面的一些值(比如 delete_flag );
controller 的 query 用 Query 接收,然后返回给前端的时候给 VO ,这里需要 DO -> 转换,因为查的是数据库返回的是 DO (如果用的是 mybatis-plus 的 page 查询,可以直接用 covert 的 lambda 函数。
其他用的不多
joyhub2140
2023-11-16 09:40:41 +08:00
哈哈,我自己就 2 个,一个是 DTO 作为 request 入参的,一个 RTO 返回给 response ( return object )。
xiaocaiji111
2023-11-16 09:46:53 +08:00
不要为了用而用。一些 O 是必须得,一些 O 只有业务需要得时候才存在,并且跟语言没关系,比如换成 go ,接收请求参数,响应数据和数据库持久化也一样,也需要分别定义,当然有人一把梭一个 O 从头传到尾,当我没有说。
yazinnnn0
2023-11-16 09:48:43 +08:00
一般 VO 、DTO 、Entity 就够了
dif
2023-11-16 10:05:29 +08:00
Entity = 数据库表 ,字段类型一一对应。
DTO = 查询数据库结果、也可做请求参数、controlelr -> service ,service -> mapper(dao)
VO = 返回给前端的对象
这就够了,除了 VO 和 entity ,其他都可以用 DTO 。

最简单,最直接,Map<Stirng,Object>一把梭,拉屎贼通畅,就是不好擦屁股。
chaleaochexist
2023-11-16 10:08:27 +08:00
取之于 v2ex.
用之于 v2ex.
https://files.catbox.moe/5d65ey.png
Masoud2023
2023-11-16 10:11:37 +08:00
我说直接点,这都是前代 Java 人拉的屎。

什么 BOPOVO ,老子就是愿意 Entity+DTO ,谁管得着?
zpf124
2023-11-16 10:16:04 +08:00
因为这些概念是重叠覆盖的。

比如 POJO , 什么 POJO ,只有属性没有方法的类都算,你提到的所有 O 都属于 POJO 细分后的一种。

什么是 DTO ,传输对象。 只要你用来当参数或者结果集的对象都算 DTO , 所以 VO,PO,DO,BO 那些乱七八糟的 O 也都是可以算 DTO ,只是阿里发布的许多文档之类的,DTO 单独用来指那些不好归类到 VO ,PO 之类 O 的其它传输对象了。

如果你分层没像阿里或者其它复杂项目架构一样切的非常细,那么你所有不知道该叫什么的都叫 DTO 就行,或者 POJO 不带后缀都可以。


--------------

再接下来说说我的理解

VO: 不论是叫它值对象(Value Object),还是展示层对象(View Object) 都是一个意思, 指的是展示层专用的、用来包装外部输入、输出的对象。
举个例子,(假设在没有前后端分离的项目中,后端需要校验表单输入)比如用户注册接口参数对象,包含字段 登录名、密码,确认密码、验证码; 确认密码字段对于后续处理没有意义,只在 view 用于校验,所以它可以是一个单独的 VO 对象,重复密码正确后,将这个 VO 中有用的部分复制给 service 层专用的入参对象。

BO:业务对象(Business Object), 感觉好像只在阿里系规范用的比较深度的项目见过 XxxxBO ,我在小厂混没实际见过。
继续以上一个例子说,注册的 VO 中有价值的部分重新组装的数据传输对象就是 BO ,RegisterBO ,这个 Bo 包含登录名、密码等等,像上一个里提到的验证码,有些人是把它算额外的另一个单独业务处理,在 Controller 中调用其它方法直接校验了,所以这里的 BO 就不包含这个对象,而有些人则是认为验证码也是业务流程的一部分,应该归到这个 BO 里,在这一层处理。

DO:持久化对象,基本就是与各类存储服务库表结构对应的对象,我常见的写法里也没见人加 DO 后缀的, 这个没什么好解释的。
上一个 RegisterBO 中 可能最后会组转成,User 对象、UserExtra 对象、WechatUser 对象、Oauth2User 、SmsLog 等对象分别存储到各自的表里面。


---------
最后:

DDD 那一套还有严格按照阿里发布的规范搞的某些项目可能会区分这么多 O ,划分这么多层, 甚至还有的入参都从 VO 、BO 、DTO 里拆出来,单独叫 Execute 、Query 、RequestParam ,Command 。

但没那么多概念的项目我们实际上不会分那么细,从 Controller 到 Service 不管多少层,除了持久化对象,入参出参都叫 DTO 的项目也有。

把不同层的数据对象拆开最大的好处就是方便项目拆分,独立部署,每个项目只需要依赖自己层的对象,当项目跨部门甚至跨公司的时候方便上游改动时控制影响范围,以及避免下游改动涉及到上游时还得跨部门让别人配合扯皮。
如果整个项目所有部分的所有权都在自己手上时,不分那么细改起来也不麻烦。
limyel
2023-11-16 10:16:20 +08:00
@mangojiji 可以的,Controller 直接透传给 Service 。

定义各种 O 的本质就是分层,保证不暴露一些不安全的字段,只要确保这个就行了。你看一些开源的商城项目、CRM 系统会直接把 Entity 返回给前端。规矩是死的人是活的,初学者很容易纠结这些问题,因为想找到一些“最佳范式”,这很正常。多写多看多问,问题不大。
nthin0
2023-11-16 10:21:48 +08:00
两到三个 O 梭哈全场 +1
具体是 2 还是 3 ,取决于数据库的数据和给前端的数据差异大不大
zpf124
2023-11-16 10:24:31 +08:00
@mangojiji
他提到的做法就是 controller 入参出参用 VO ,数据库表对应对象用 PO ,中间的 service 或者其它 Job 、Util 、甚至连查表的返回对象和数据库查询参数之类的传输对象都用 DTO 。
Daniel17
2023-11-16 10:24:32 +08:00
不要那么多 O ,太多了代码都不好写
dddd1919
2023-11-16 10:38:29 +08:00
@MrSheng 前端交互 VO ,内部数据传递 DTO ,数据库映射 Entiy
HelloWorld556
2023-11-16 10:40:54 +08:00
我是和数据库交互的用 DO ,其他全部 VO
xiaobucvg
2023-11-16 10:56:18 +08:00
VO: 前后端分离, 用不到
sampeng
2023-11-16 10:57:01 +08:00
这都是卷的结果。。
2bad4u
2023-11-16 10:58:36 +08:00
@joyhub2140 request 入参 DTO 只有一个 int id 参数,也要写一个 dto 文件吗?
jorneyr
2023-11-16 10:58:48 +08:00
除了 CTO ,我啥都不管,CTO 让用啥就用啥。
kuber
2023-11-16 11:08:37 +08:00
建议题主看一下这本书 [企业应用架构模式] ,里面有详细的说明,以及不同情况下的选择。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/992296

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX