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

关于 Java 中的 DO、DTO、BO、AO、VO、POJO 有没有人能用一个接口的例子通俗的解释一下?

  •  
  •   itechnology · 181 天前 · 5689 次点击
    这是一个创建于 181 天前的主题,其中的信息可能已经有所发展或是发生改变。
    阿里巴巴 JAVA 开发手册是这样定义的:

    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 等。

    但我感觉光看定义还是不容易理解,有没有人能用一个接口的来举个例子说一下
    53 条回复    2022-04-28 08:45:02 +08:00
    Oktfolio
        1
    Oktfolio  
       181 天前   ❤️ 1
    DO selectByPrimayKey(Long id);

    DTO selectJoinedXxxx(Query quer);

    BO toBo(DO do);

    void addSomeBizData(BO bo);

    void doSomething(BO bo);

    interface api {
    DTO getById(Long id);
    }

    @Get("")
    VO getXxxxxVo(Long id);

    @Post("")
    void create(CreateXxxDTO dto);

    我是这么用的
    leeyuzhe
        2
    leeyuzhe  
       181 天前
    @Oktfolio 但这些数据结构互相转不是造就了很多无用代码,如果两种结构区别不大的话
    welong
        3
    welong  
       181 天前
    DTO VO BO 这几个用到的比较多吧。
    timethinker
        4
    timethinker  
       181 天前   ❤️ 26
    画了一张图,凑合看吧

    notwaste
        5
    notwaste  
       181 天前
    感觉没必要规定死,每个地方有每个地方不同的定义,目的都是统一规范罢了,个人认为只需要了解分层就可以,比如跟数据库交互的对象是一层称为 DTO ,controller 跟前端返回的对象是一层叫 VO (我们公司定义叫 Result )
    NotFoundEgg
        6
    NotFoundEgg  
       181 天前
    我平时的习惯是
    controller 接收参数的实体类命名为 DTO 、返回的实体类命名为 VO
    在 controller-service 、service-service 中传递的实体类命名为 DTO
    DAO 的返回命名为 Entity
    javapythongo
        7
    javapythongo  
       181 天前   ❤️ 3
    遇事不决 dto
    lower
        8
    lower  
       181 天前
    我是一个 Entity 走天下,,实在不行用万能 Map 上
    lululau
        9
    lululau  
       181 天前
    有用 Kotlin 写 Web 的吗,我想知道 Kotlin 里也这么多欧吗
    me221
        10
    me221  
       181 天前
    这么多 o 太晕了 我只用了 entity vo dto
    lopssh
        11
    lopssh  
       181 天前
    @qwe520liao 用什么工具画出来的呀?
    wolfie
        12
    wolfie  
       181 天前
    DTO 接参
    DO 略
    VO 渲染
    BO 跟入参、响应 无关的,临时处理用的。
    echo1937
        13
    echo1937  
       181 天前
    @lower #8 遇到万能 Map 最头疼了,不跑一次很难知道里面都有啥,魔术袋。
    q474818917
        14
    q474818917  
       181 天前
    以一位从业多年经验告诉你,远离 java (这个最内卷的语言,没有之一)
    itechnology
        15
    itechnology  
    OP
       181 天前
    @wolfie 感谢解释,简单明了
    timethinker
        16
    timethinker  
       181 天前
    Stevenv
        17
    Stevenv  
       181 天前
    原来不是我一个人。,。。。。
    chrosing
        18
    chrosing  
       181 天前
    映射数据库用 entity 入参用 vo 出参用 dto
    xiangyuecn
        19
    xiangyuecn  
       181 天前
    Map 一把梭😂
    Leviathann
        20
    Leviathann  
       181 天前
    感觉有些时因为当时没有 graphql
    有些是为了类型安全
    但是由于是名义类型,所以必须声明一个 object 出来
    像 ts 是结构类型,只要字段一样就可以,返回一个 object literal 也能匹配上
    BeautifulSoap
        21
    BeautifulSoap  
       181 天前
    所有对象中所,核心是 Business Object(或者理解成 DDD 中的 Entity 也行),写代码或者建模也应该是以 Business Object/Entity 为核心创建,其他都是围绕着 Entity 的。比如你想要持久化保存 Entity ,那么你自然就需要 Data Object ,因为同一个 Entity 保存在不同数据库甚至是调用微服务保存的时候,存储用的结构是会非常不一样的

    然后你想要把 Entity 的内容从 API 返回给调用方、或者吧 API 的请求参数复原成 Entity 的话,你也需要个对象来存放这种数据,那就是 DTO
    qingshuang
        22
    qingshuang  
       181 天前
    我一直以为 DO 是 Domain Object 。。。
    qingshuang
        23
    qingshuang  
       181 天前
    DO 我们这里一般都叫 PO
    chocotan
        24
    chocotan  
       181 天前
    Entity 一把梭
    djFFFFF
        25
    djFFFFF  
       181 天前
    @chocotan 感觉一把梭的话叫 DTO 比较好,Entity 通常用来表示数据库对象,就是 4 楼的 DO
    stephCurry
        26
    stephCurry  
       181 天前   ❤️ 1
    甚至可以创造一个 RO Request Object...
    Jooooooooo
        27
    Jooooooooo  
       181 天前
    通通 vo 一把梭
    flyfanc
        28
    flyfanc  
       181 天前
    太复杂了,只用 entity ,其它情况 map
    sagaxu
        29
    sagaxu  
       181 天前 via Android   ❤️ 3
    等你把 5 个 O 的 class 写好的时候,PHP 用万能 array 堆起的小屎山已经提测
    flighter
        30
    flighter  
       181 天前
    DO 不是 Domain Object 么?
    newskillsget
        31
    newskillsget  
       180 天前
    @lower 来人呐,把这个用 map 传参的拉出去枪毙十分钟
    orange
        32
    orange  
       180 天前
    @sagaxu 形象 :)
    mritd
        33
    mritd  
       180 天前 via iPhone
    歪楼

    潘森: 踩住 OOO 接 扎 接 碘盐 接 突突突
    fpure
        34
    fpure  
       180 天前
    我写的代码里面一般只会存在简单的 model 、Query 、VO 三种对象
    Bingchunmoli
        35
    Bingchunmoli  
       180 天前 via Android
    @leeyuzhe 学习的时候确实无用代码,但工作后各种需求,各种数据实体需要来回转换就有必要了
    yogogo
        36
    yogogo  
       180 天前
    只用 entity dto
    数据库 entity
    接口 dto
    EvanLuo42
        37
    EvanLuo42  
       180 天前 via iPhone
    @lululau ktor 吗,一般用个 dataclass 就好了吧
    Rocketer
        38
    Rocketer  
       180 天前 via iPhone
    我个人的理解是:

    POJO 就是 Entity ,是数据对象的终极形态。

    但持久端可能使用不同的数据库,以后还有可能换库,所以 Entity 要转成数据库相关的 DO 才能存储。在某些情况下,Entity 和 DO 可能一模一样,但为了以后换库方便,仍然需要转一下。

    DTO 是 Service 向 Controller 输入输出数据用的,有时是处理过的,有时跟 Entity 一模一样。但为了命名统一,还是要转一下。

    其他 O 不知道是干啥用的,现在 Controller 返回的都是 JSON ,应该没有 VO 了吧?
    offswitch
        39
    offswitch  
       180 天前
    @qingshuang Domain Object 这个是领域对象,是 DDD 里面的概念。
    NeoZephyr
        40
    NeoZephyr  
       180 天前
    @lower Entity 指的是什么
    NeoZephyr
        41
    NeoZephyr  
       180 天前
    @newskillsget 我们全部用的 map ,挺好的啊
    NeoZephyr
        42
    NeoZephyr  
       180 天前
    @q474818917 你说哪个不内卷啊
    Asuka0947
        43
    Asuka0947  
       180 天前
    只用 entity ,vo ,bo ;偷懒 entity 一把梭了,忽略部分字段。
    LowBi
        44
    LowBi  
       180 天前 via Android
    偷懒了,太多了也太绕
    newskillsget
        45
    newskillsget  
       180 天前
    @NeoZephyr 开发的时候时方便了,维护起来会要了老命(除非有及时更新的文档)
    MonkeyJon
        46
    MonkeyJon  
       180 天前
    目前在用:
    VO:用于跟前端对接的出参(返回结果)
    DO:微服务之间的数据传输
    POJO:只跟数据库交互使用
    DTO:PO 满足不了的用 DTO 重写 PO 字段与数据库交互
    AO:我们是 Query,前端传的入参,仅存在于 Controller 层
    BO:我们命名为 Params ,query 转 params 才能进入 service 层
    itechnology
        47
    itechnology  
    OP
       180 天前
    @MonkeyJon 感谢解释
    sknyyh
        48
    sknyyh  
       179 天前
    @lower Map 维护的时候,真的是火葬场
    Uplay
        49
    Uplay  
       176 天前
    @lululau 我们就用的 kotlin 感觉跟其他没什么区别
    wshcdr
        50
    wshcdr  
       175 天前
    @qwe520liao AO 这里能举个例子不?
    timethinker
        51
    timethinker  
       175 天前
    @wshcdr 简单的来说,你可以把 Controller 里面的一些逻辑转移到一个 Application Object/Service 上。

    分析一下原因,按理说每一个接口的逻辑应该是不同的,唯一的,但是不同接口之间可能也会复用到一些应用逻辑,如果这些逻辑在同一个 Controller 的不同的 Method 上( RequestMapping ),或许可以简单的创建一个私有的方法来搞定这些复用的逻辑。

    但是对于不同 Controller 需要复用的逻辑,又不适合放在普通的 Service 上,就可以创建一个 Application Object/Service 来封装了,此时的顺序变成了:

    Controller -> Application Object/Service -> (Domain)Service -> Repository/DAO 。

    另外再说一些题外话,大部分人应该没有这些顾虑或者思考,看不懂的略过即可:

    在 DDD 的战术模式中,领域服务( DomainService )一般只对单个聚合进行操作,且这些操作属于该领域自己的业务逻辑,只是不适合放到单个聚合上面,最重要的一点,聚合的任何操作都保证了不变性条件。

    但是某一个业务需求可能会跨聚合进行操作,又要保证事务一致,就可能会在上层再建立一个应用层,注意我这里说的应用层跟 DDD 中的应用服务( ApplicationService )不一样,它跨聚合操作这种行为本身就是因为模型分析得不到位。因此这种逻辑是不推荐的,因为它模糊了限界上下文之间的关系,但是从编码角度来说却是很方便的。

    想一想我有好几个 Service ,然后在 Controller 里面依次调用,只需要在 Controller 方法上加一个 @Transaction 的注解就可以保证事务一致,其中任何一个 Service 失败都将回滚数据,保证数据的一致性不被破坏。但其实这是一种偷懒的做法,或者说在是规模小的时候一种取巧省事的办法。
    NeoZephyr
        52
    NeoZephyr  
       174 天前
    @newskillsget 也还好吧。每个人只关注自己往里面 put 的数据,别人 put 的都不动
    rehoni
        53
    rehoni  
       110 天前
    为什么米有 Qo ,不过我基本只用 QO,DTO,VO,ENTITY
    QO:controller 接口接收的参数,POJO 类,用 oval 注解参数校验,至于直接用 QO 还是转换成 DTO 再给 service ,看心情...
    DTO:service 单表,联表查询返回的对象,POJO 类,继承 ENTITY ,用 excel 注解实现导出
    VO:特定约定返回给前端的结果用 VO ,从 DTO 做数据结构转换成 VO
    ENTITY:实体类对应数据库
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3301 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 10:29 · PVG 18:29 · LAX 03:29 · JFK 06:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.