请教各位一个概念和具体应用上的问题, VO, BO, PO, DO, DTO 这些概念和具体应用应该是怎样的?

2023-03-29 15:40:39 +08:00
 chirsgod

最近被项目里各种各样的 O 给弄点有点有点迷茫,问了下 ChatGPT 后和搜索引擎的结果对比了下,感觉也是略微有所出入,每个人对这些理解都不是完全一样的。想请教下正确的具体概念,最后能提供一个好的开源项目,供我学习具体代码上的应用。谢谢大家

3811 次点击
所在节点    Java
29 条回复
moshiyeap100
2023-03-29 15:41:50 +08:00
BO: 业务层传递用。
moshiyeap100
2023-03-29 15:43:11 +08:00
BO: 业务层传递用。
VO: 给前台或者 api 返回。
DTO: 接口入参
DO: 数据对象,我们基本不用。
PO:也基本不用。

主要还是看你们自己的标准吧。
a379395979
2023-03-29 15:45:41 +08:00
感觉就 java 搞了一堆 xxo ,其他语言就没这些。
jorneyr
2023-03-29 15:47:46 +08:00
一个普通的 POJO 都能搞定的时候,就不用这些 XO 。
大多数业务其实一个 POJO 就能满足,例如 User 就够了,不再搞 UserDto 、UserVo ,UserBo 了。
chirsgod
2023-03-29 15:49:13 +08:00
@moshiyeap100 #2 那我想问一下,假如一个表对应建了实体类以后,和另一个实体类之间存在一对多或者多对多的关系,合理的做法是直接维护在实体类里,还是维护在 PO 里或者哪里呢?
moshiyeap100
2023-03-29 15:53:11 +08:00
@chirsgod 那我们来说,以前写 jpa 的时候会关联,现在不会了,各自是各自的。如果有连表查询的结果,通过继承或者新建一个对象。
nothingistrue
2023-03-29 16:01:15 +08:00
历史遗留概念,不是搞来龙去脉研究的话,没必要去弄明白了。现在如果你用 JPA ,六边形架构就只有 Entity 和 普通 Data 的区别,分层架构最多再多个 View Object (一般也没人回去加这一层,能不 open session in view 就谢天谢地了)。如果你不用 JPA ,不过你开始分得多么清楚,不出一个月就都会变成单层的 普通 Data ,连 Entity 都区分不出来。

最大的幸运,或者最大的问题是,以上都行得通。
kaf
2023-03-29 16:04:30 +08:00
这种都是复杂业务产生的东西,开源项目也很难表达这些。结合个人业务解释下这些东西,我这边业务数据基本都是十几个数据源,涉及到很多个公司和时间维度的记录,有些要从其他服务获取,有些在自己数据库,归类这些就需要定义各种类型,PO 是获取数据源的对象,DO 在我们业务系统一般用不到,DTO 是请求三方服务的格式定义,同时业务要对这一对数据做汇总,就要在转换到 BO ,用统一的数据接口做计算,而后端一般都是把各个维度的数据统一铺平计算,都是[公司,时间,业务类型,业务数据]这样,但是前端展示可能会以[业务类型,时间]这样展示,甚至前端很多时候需要一些树结构数据,需要 bff 层转换数据到 VO 提供给前端
BQsummer
2023-03-29 16:37:49 +08:00
虽有时候觉得这么多 o 很蠢, 但是有的屎山代码一个 req 一路捅到底, 请求进来的时候塞点东西, 数据查出来的时候塞点东西, 多个接口用一个 req, req 还传到线程池里处理, 当成了 context 来使用, 真的很难维护.
knightdf
2023-03-29 17:27:23 +08:00
都是一堆大厂搞出来的规范,没必要遵循
yule111222
2023-03-29 17:44:54 +08:00
这些东西是整洁架构里非常有必要的,不过你分不清说明你们的工程架构本身也是一团浆糊那就不用分了。。。
chirsgod
2023-03-29 18:52:51 +08:00
@nothingistrue #7 好的明白了,我现在在维护的项目里有这些东西,我怕搞不清楚具体用途最后乱写一通,你这么说我心里负担小了很多
howfree
2023-03-29 20:00:17 +08:00
阿里开发手册上都有
sadfQED2
2023-03-29 20:15:37 +08:00
在我这里。没那么多 O ,我都是 map<object,object>捅到底🐶
Comyn
2023-03-29 20:47:26 +08:00
我们就用 entity(与数据库表一一对应),dto 接收前端参数,vo 返回给前端的
justNoBody
2023-03-29 21:02:01 +08:00
要结合实际业务来讲更合理。
比如我现在有一个用户登录的业务(这个业务虽然都被大家讲烂了,但确实是最容易懂的业务了)

你得有一张表存用户数据吧,就叫 user 表吧,这个表里面有 id ,name ,password

那么你现在需要实现一个登录,那就只需要检查用户输入的 name 和 password 和数据库是否一致就可以了。
这种情况下,你就用一个 User 对象来表示这个领域模型就可以了。我一般用 Domain Object (也可以说是 Data Object )也就是 DO 表示,对应下来就是 UserDO ( D 和 O 都大写的原因也是因为阿里巴巴的规范是这样的,所以大家一般情况下都这么来,我个人也能喜欢这种风格。如果你司统一用 Do 也可以,无所谓的,就是别一会儿全大写,一会儿大小写混着用就行了。或者你司不用 DO ,用其他的也可以,叫什么不重要,只要内部统一即可,重要的是表达什么意思)

再假设我现在有一个展示用户信息的业务,假想给一个客服(类似于管理员,但是又比真的系统管理员的权限低,就是不期望把用户密码给他看到的那种情况)
一般来说有两种做法:
第一种,你可以在序列化为 json 字符串的时候,隐藏 password 的序列化来实现;
第二种,你可以新建一个 VO ( View Object )对象,就叫 UserVO ,然后这里面就只有 id 和 name 两个属性即可;

再假设,我现在不是直接展示到页面上,我现在是被一个业务系统调用,这个系统需要依赖于我这个登录的服务。
然后我需要提供 sdk 给这个业务系统集成,那么这个时候,就可以声明一个 DTO 对象,里面也只有 id 和 name 属性即可。

实际业务肯定不可能说只有 id ,name ,password 这么简单。

对于楼上说的一个 bean 搞定或者用 map 的,我真心不建议,过于宽泛会使得模块内聚降低(就是这个模块输入输出的可能性非常多,很容易和其他的业务模块产生不可替代性的耦合),程序本身健壮性会很差,如果时间一长,开发 A 加个属性,开发 B 加个属性,最后就会变成屎山。
auh
2023-03-29 21:19:23 +08:00
去问架构师,这是傻逼架构师发明的。
shimada666
2023-03-29 23:36:41 +08:00
我们 xxRequest 收前端参数,xxVO 返回前端,DO = entity 和数据库字段一一对应,请求第三方接口用 BO
Biluesgakki
2023-03-30 08:59:02 +08:00
我们项目简单 只用一个 entity 和 vo 要拿来接收参数、计算等多出来的字段都放 vo 里。感觉用 BO 、DO 、DTO 一大堆转来转去也实在麻烦。。
mmdsun
2023-03-30 09:37:58 +08:00
小项目一个对象可以弄到底。

校验用分组校验,隐藏部分字段用 @JsonView 注解

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

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

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

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

© 2021 V2EX