初入 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…能力有限

最好能够配合示例代码或者伪代码,谢谢大佬们。
14132 次点击
所在节点    Java
94 条回复
FantaMole
2023-11-16 11:10:16 +08:00
说白了,搞这么多 O ,实际上还是项目工程化的要求。不做这些分层就写不了代码了吗,那肯定不是的。就像你要是乐意,可以把所有代码逻辑都写到 main 里,但是你肯定不会这么写,因为太难维护了。分层是在项目复杂化之后的为了方便维护的必然结果,如果你以后维护过屎山代码之后你就会更有体会了。

所以反过来说,要不要这么多层级结构,也是根据项目的复杂程度来的,如果项目并不复杂,你并不需要这么多,就像上面很多楼说的,PO/Entity 、VO 、DTO 差不多就可以让项目结构比较清晰了
bill110100
2023-11-16 11:11:19 +08:00
现在还入 java ,49 年入国军了。
bill110100
2023-11-16 11:14:29 +08:00
这些都是缩写,先去查一下原始的英文单词是哪个,你就自然明白这些要怎么用了
skwyl
2023-11-16 11:16:53 +08:00
初学你不用管这么多的,MVC 就成
Dao 与 Service 传输用 Model ( PO ) 然后 Service 与 Controller 之间用 VO 记住这俩就行了,先把项目积累起来在考虑这这种加层
gowk
2023-11-16 11:55:43 +08:00
为什么我只使用 DTO ,不管其他“O”? https://mp.weixin.qq.com/s/mhl6SVHZvNp6BeqfeupCQw
godleon
2023-11-16 11:56:57 +08:00
CRUD 不用太在意这些

简单的方式,写一个 baseEntity 公共字段, 写一个 queryParam 查询参数, 用业务的 entity 继承一下就行了

如果按上面说的你用 dto 接,转 entity 存到 db ,转你不耗费资源吗? 如果上百个字段的 dto 你转去吧
potatowish
2023-11-16 12:00:36 +08:00
@cooper 这种应该是最常见的,只分三层就比较清晰了
sprite82
2023-11-16 13:19:16 +08:00
hello158
2023-11-16 13:49:34 +08:00
通常,在我们设计一个模块的时候,
我们设计的是一个又一个 Entity,实体,Entity 之间又各种各样的关联关系。
Entity 构成了我们的主要设计,实际 Entity 的数据需要持久化落地的时候,就用用到 PO ,Entity 和 PO 并没有直接关系,一个 Entity 最终落地数据库的时候可以是多张表,即对应多个 PO 。

DTO 是用来数据交换,VO 是用来展示层的。

就这这些,没啥难的的,至于 BO ,不知道,自己灵活变通即可,也许 BO 代表 BusinessObject,那就跟 DTO 差不多一个意思了。

总结下来:因为我们是面向对象编程,所以需要设计实体 Entity,实体不太表数据库表,实体代表我们抽象的业务模型。最终数据需要落地,落地就需要数据表 对应的就是 PO 了,你爱咋存咋存;中间需交互数据,或者吐数据,我们通常没法把实体 Entity 直接给别人,可能是根据业务需要,将多个实体中的数据抽出来,凑出一个 DTO ,或者 VO 给别人用。

你开发经验够了,这些东西想清楚了,你就能整自己的一套,也能理解别人的套路。

就是不能觉得繁琐而无脑抵制。不过,你当然可以面向数据库表编程,一个 calss 从前到后。
gejun123456
2023-11-16 13:53:58 +08:00
小项目无所谓的,直接 controller 调用 mapper 调用拿数据库对象返回都行,后面有需求可以再加 一层转的 service 和 vo
bugmakerxs
2023-11-16 14:20:27 +08:00
数据库结构 DO ,页面返回 VO ,其他都是 DTO

也有接口请求 Req 后缀,返回 Resp 后缀,其他都 DTO 的
blackshow
2023-11-16 15:24:49 +08:00
没逼用,把时间花在有用的东西上吧。。。
chf007
2023-11-16 16:18:07 +08:00
前端出身,没专门做过 Java ,但是维护过 Java 代码,个人理解的各种 O:

首先为什么要有 O ,Java 是一个支持类型的语言,一个 Web 业务里各个层的方法不可能出入参都是简单类型,复杂出入参要是不写专门的类型就如 @dif 说的,可以直接入参一个变量为 Map<Stirng, Object>,返回也是,但是很明显不优雅, 比如无法编辑器自动提示,无法自动生成有意义的接口文档,所以最好要写个专门的类文件去定义,那这个类文件叫啥名呢,可以叫任何名,类名也可以叫任何名,只不过为了团队统一,约定叫 dto vo do 什么的,其实就是一个普通的 java 文件。

第二为什么要分开各种 O ,上边说了,这个主要是为了支持类型的,那很明显分层多了后,不同层的出入参虽然字段可能都一样,但自已都在做自已的事,本质上就不是同一个类型了,要是还用同一个 O ,迟早会遇到这一层要加个什么东西,但另外一层不需要加,这里时候要么你改,要么别人改,所以不如一开始就分开。

总之一句话总结:Java (或者说 Spring 这种框架)各种方法的出入参最好要有一个独立的类型来表示,那这个类型文件就是 O ,各种方法又分 Controller 的,Service 的,那类型文件最好不要用同一个,最好自已定义自已的,那就分开了各种 O 。
zzhaolei
2023-11-16 16:36:40 +08:00
现在我待的公司的 go 代码也是有很多 DTO😂
e7
2023-11-16 17:06:30 +08:00
为了方便归类人为搞出来的概念,你项目中完全可以不带 O ,没那么方便而已
ruzztok
2023-11-16 17:09:52 +08:00
管他什么 O ,统一一个 DTO 用的死!!! haha
wqhui
2023-11-16 17:18:58 +08:00
分太细像坨💩,一模一样的内容 copy 四五份,用两三个区分下数据库对象跟其它就行了,旧项目就跟着用
label
2023-11-16 17:24:52 +08:00
过度设计的产物
Tenlearn
2023-11-16 17:28:29 +08:00
有个卵子用,能跑就行,你看着清晰就行,叫啥能帮助 gc 还是能不触发 bug
popvlovs
2023-11-16 17:59:46 +08:00
分的太细违反设计原则,建议忽略,有规范 follow 规范,没规范看心情

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

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

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

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

© 2021 V2EX