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

service 层接收的参数 xxRequest 还是 xxDto ?

  •  
  •   jerrry · 2020-07-14 14:10:14 +08:00 · 5167 次点击
    这是一个创建于 1353 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如 UserController 中有 List<UserDto> findUsers(UserSearchRequest xxRequest) { return userService.findUsers(...) } 方法,

    那么 UserService 中的 List<UserDto> findUsers(...) 接收的参数应该怎么设计 ?

    其中 UserSearchRequest 包括多个查询条件 ( keywords, username, age, time, city... ).

    32 条回复    2020-07-15 10:47:34 +08:00
    damai0419
        1
    damai0419  
       2020-07-14 14:55:24 +08:00
    直接用也可以,要么创建一个 xxxQuery 也可以。
    zhangdashuan
        2
    zhangdashuan  
       2020-07-14 14:57:17 +08:00
    param
    sheeta
        3
    sheeta  
       2020-07-14 14:58:34 +08:00
    我用的是 xxRequest
    lqs
        4
    lqs  
       2020-07-14 15:43:40 +08:00
    原则上 Service 层应该单独有一套业务对象,这样就可以把 UserService 里的接口设计成 List<UserBo> findUsers(UserSearchBo),然后在 UserController 里对输入输出都做适配。
    luxinfl
        5
    luxinfl  
       2020-07-14 15:48:55 +08:00
    我们小公司,没那么复杂,对外统称 dto 。有时候还用 domain 来作入参和返参。
    jerrry
        6
    jerrry  
    OP
       2020-07-14 19:05:39 +08:00 via Android
    @lqs 但是我的 controller 和 service 对应的查询参数一般都是一样的,所以这时候不知道怎么设计...
    jerrry
        7
    jerrry  
    OP
       2020-07-14 19:06:29 +08:00 via Android
    @luxinfl 对请求参数检验的话还是封装在 vo 里比较方便吧
    wshcdr
        8
    wshcdr  
       2020-07-14 20:32:27 +08:00
    关注一下
    hantsy
        9
    hantsy  
       2020-07-14 21:25:07 +08:00
    UserDto 这种太通俗了。

    如果你想让你的代码做到 Self Documentation,可以学习 Spring 的命名,尽量取一个有意义的名字。

    如果应用了 CQRS,很多命名相对容易些。CreateUserCommand, UserCreatedEvent, 等。

    总之,尽量做到一个 Dto 仅仅封装所需要的数据,见过一些人为了省事,用一个巨无霸 Dto,完全没把 OOP 放在心上。
    hantsy
        10
    hantsy  
       2020-07-14 21:26:49 +08:00
    @lqs
    @jerrry

    VO,BO 是什么鬼东西,我写了十几年 Java,读了 N 多本书,没见过。
    hantsy
        11
    hantsy  
       2020-07-14 21:28:07 +08:00
    Value Object ???
    hantsy
        12
    hantsy  
       2020-07-14 21:28:46 +08:00
    DDD 中 Value Object 是相对于 Entity 来讲的。
    Sharuru
        13
    Sharuru  
       2020-07-14 21:30:15 +08:00
    xxxForm,xxxModel,xxxParam 。
    针对楼主的场合,可以用 xxxCriteria 。
    MarioLuo
        14
    MarioLuo  
       2020-07-15 01:00:50 +08:00 via Android
    命名重要保持一致性就好,不过个人更倾向: XxxParams, XxxQuery 代表入参, XxxDTO,XxxInfo 代表出参,更符合自然语意些
    oneisall8955
        15
    oneisall8955  
       2020-07-15 01:24:09 +08:00 via Android
    跟项目,假如新项目看自己喜好
    daimubai
        16
    daimubai  
       2020-07-15 01:41:06 +08:00
    随主流
    接受用 xxxDTO ( DTO 大写可读性更高点吧)
    响应用 VO
    jerrry
        17
    jerrry  
    OP
       2020-07-15 05:13:38 +08:00 via Android
    @hantsy view object, api 返回的数据一般是和 entity 不一致的。
    jerrry
        18
    jerrry  
    OP
       2020-07-15 05:19:05 +08:00 via Android
    @Sharuru 谢谢,那如果它们所需的参数是一致的情况下,controller 层需要的参数对象和 service 需要的参数对象需要分成俩个吗?
    yalin
        19
    yalin  
       2020-07-15 08:39:37 +08:00
    都是 DTO 层
    memedahui
        20
    memedahui  
       2020-07-15 08:47:51 +08:00
    最近刚好看了一个类似的文档,说的就是一共需要 3 个:
    接入层模型:view object 与前端对接的模型
    业务模型:领域模型,业务核心模型
    数据模型:
    memedahui
        21
    memedahui  
       2020-07-15 08:49:21 +08:00
    最近刚好看了一个类似的文档,说的就是一共需要 3 个:
    接入层模型: view object 与前端对接的模型
    业务模型: domain object 领域模型,业务核心模型
    数据模型: data object 数据模型,同数据库映射
    liuxey
        22
    liuxey  
       2020-07-15 08:52:05 +08:00
    @hantsy #10 bussiness object,远古时代 Java 里对象名字可太多了:BO VO DTO DO POJO
    hantsy
        23
    hantsy  
       2020-07-15 09:06:49 +08:00
    VO= Value Object,我觉得还不错,如果是 View Object,呵呵,这种创造太恐怖了。
    hantsy
        24
    hantsy  
       2020-07-15 09:10:29 +08:00
    @MarioLuo 接受自然语言这一条不错。
    实际各种层的传输数据,另外还有一个特质,Immutable 。
    passerbytiny
        25
    passerbytiny  
       2020-07-15 09:38:13 +08:00 via Android
    DTO,Data Transfer Object,数据转换对象。你要真是个 DTO,那是一个有状态 Java Bean (并且带大量方法,或者要用到工厂模式等各种模式),一般人用不起。

    如果要求上下层互不依赖,需要 DTO 来解藕。否则,谁是被依赖方,用谁定义的对象。
    RedBeanIce
        26
    RedBeanIce  
       2020-07-15 09:50:20 +08:00   ❤️ 1
    DO ( Data Object ):与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
    BO ( Business Object ):业务对象。由 Service 层输出的封装业务逻辑的对象。
    DTO ( Data Transfer Object ):数据传输对象,Service 或 Manager 向外传输的对象。
    VO ( View Object ):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
    Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类来传输。

    以上摘抄自阿里巴巴 Java 开发手册(参考部分)
    Rwing
        27
    Rwing  
       2020-07-15 09:57:21 +08:00
    所有用 XXO,XO 都是懒人,这种废话写不写没什么意义,不能准确表述意图
    ylsc633
        28
    ylsc633  
       2020-07-15 10:00:07 +08:00
    这问题不是 脉脉 里的么.....
    tang123456
        29
    tang123456  
       2020-07-15 10:06:43 +08:00
    目前我们公司是统一传参用 dto,反参用 vo
    YzSama
        30
    YzSama  
       2020-07-15 10:13:03 +08:00
    @RedBeanIce #26 直接沿用 阿里巴巴的规范就好了。

    这个最好看看 阿里 Java 开发规范 工程设计 那块,因为 service 层 存在对外服务。例如 RPC,所以统一 DTO 是反参。

    BO 是 Service 入参 。

    如果楼主的项目里,service 只是提供 controller 的话,因此 入参和校验 其实都是从 controller 来的。并不需要修改成 BO,直接沿用就好了。还少了一层转换
    jerrry
        31
    jerrry  
    OP
       2020-07-15 10:45:42 +08:00
    @YzSama 谢谢, 受教了。 不过如果用到 BO 的话, VO 如何转换到 BO 呢?是把转换逻辑封装到 VO 的一个方法里?还是单独写一个转换器类。
    jerrry
        32
    jerrry  
    OP
       2020-07-15 10:47:34 +08:00
    @RedBeanIce BO 和 DTO 的区别好像没看出来啊。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3609 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 04:43 · PVG 12:43 · LAX 21:43 · JFK 00:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.