V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chirsgod
V2EX  ›  Java

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

  •  3
     
  •   chirsgod · 2023-03-29 15:40:39 +08:00 · 3357 次点击
    这是一个创建于 390 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    你得有一张表存用户数据吧,就叫 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
        17
    auh  
       2023-03-29 21:19:23 +08:00
    去问架构师,这是傻逼架构师发明的。
    shimada666
        18
    shimada666  
       2023-03-29 23:36:41 +08:00   ❤️ 1
    我们 xxRequest 收前端参数,xxVO 返回前端,DO = entity 和数据库字段一一对应,请求第三方接口用 BO
    Biluesgakki
        19
    Biluesgakki  
       2023-03-30 08:59:02 +08:00
    我们项目简单 只用一个 entity 和 vo 要拿来接收参数、计算等多出来的字段都放 vo 里。感觉用 BO 、DO 、DTO 一大堆转来转去也实在麻烦。。
    mmdsun
        20
    mmdsun  
       2023-03-30 09:37:58 +08:00
    小项目一个对象可以弄到底。

    校验用分组校验,隐藏部分字段用 @JsonView 注解
    bthulu
        21
    bthulu  
       2023-03-30 09:47:51 +08:00
    就一个实体就行了, 不要提前设计. 等后面确实需要综合多种渠道拿混合数据, 再改成一个 vo 就可以了.
    xiaohundun
        22
    xiaohundun  
       2023-03-30 09:56:48 +08:00
    我也挺想问的,大家公司都不分 PO 、VO 、DTO 的么?我感觉还是挺有必要的呀,尤其是 PO 、VO 至少得有吧,毕竟前端需要的东西跟数据库差别大
    xiaohundun
        23
    xiaohundun  
       2023-03-30 09:58:03 +08:00
    @xiaohundun #22 啥啥都是直接用 map 的话,后期维护不是个灾难。。
    lyf362345
        24
    lyf362345  
       2023-03-30 11:27:50 +08:00
    建议不用,Java 里的糟粕,最近公司里写 Go 的人也把这些东西搞过来了,看着挺难受的。
    lanlanye
        25
    lanlanye  
       2023-03-30 11:48:58 +08:00 via iPhone
    没有实际用过 Java ,理论上 CRUD 初期 POJO 的结构可以一路传到任何地方,只需要在前端接口变更 /数据库结构变更等情况发生时再创建对应的对象做转换就可以了。
    问题是如果一开始没做这件事,等问题发生时去处理的人又没能意识到这里需要一个现在没有的对象,项目就会逐渐变得无法理解……
    witcherhope
        26
    witcherhope  
       2023-03-30 15:03:18 +08:00
    一种工程化实践而已,就是分层和职责分离的思想,每一层的上下文语义不一样,理所当然实体要有所区分
    kaddusabagei38
        27
    kaddusabagei38  
       2023-03-30 16:01:01 +08:00
    发明出这么多层东西,然后代码里到处 copyProperties

    你们 java 真的挺好笑的
    pocketz
        28
    pocketz  
       2023-03-31 16:59:00 +08:00
    分享一个我的收藏吧,讲得蛮详细的
    https://blog.csdn.net/chenchunlin526/article/details/69939337
    pocketz
        29
    pocketz  
       2023-03-31 17:03:15 +08:00
    搞清楚缩写前的单词,能清楚一半
    VO: view object
    BO: business object
    PO: persistent object
    DO: data object
    DTO: data transfer object
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5331 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 07:10 · PVG 15:10 · LAX 00:10 · JFK 03:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.