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

一个方法很多参数,算是好的设计还是不好的设计

  •  
  •   awesomePower · 58 天前 · 6312 次点击
    这是一个创建于 58 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,一个方法含有十几个参数,这算是糟糕的设计还是好的设计,还是无所谓。 有这方面的标准么?

    50 条回复    2024-07-12 16:50:52 +08:00
    iOCZS
        1
    iOCZS  
       58 天前
    看情况,偶时候难免
    maokg
        2
    maokg  
       58 天前
    Android 源码倒有很多方法是很多参数的,但会在方法里调方法,f1(var a, var b, var c, var d){ f2(var ... x)}
    yazinnnn0
        3
    yazinnnn0  
       58 天前   ❤️ 3
    能像 kotlin 那样有默认值就不是遭设计, java 这种想要默认值需要重载无数个的是糟设计
    goxxoo
        4
    goxxoo  
       58 天前   ❤️ 1
    十几个算啥? 我遇到过一个接口里大几十个参数的, 连调用哪个参数实现功能,都特么没写的
    qping
        5
    qping  
       58 天前 via Android   ❤️ 3
    实在太多,就建个 options 类,包一下。我们想要参数越少越好,但有时候很困难
    jackmod
        6
    jackmod  
       58 天前
    有条件就包装成新的类。含义相似参数塞太多是很糟糕的,但一般这种时候都可以甩锅🐶
    比如有些 ORM 不支持动态数量的参数(或者说传一个 List ),那就只好塞到 255 个了🐶
    woodfizky
        7
    woodfizky  
       58 天前
    举个例子,ElasticSearch 的 Python 包,8.0.0 的,AsyncElasticSearch 类的 search 实例方法,我数了一下大概 60 多个参数。。不过全部是默认参,进到方法里面再具体做了参数校验或判断,一般情况实际传进去的参数比较少。

    有时候没办法啊,场景就决定了参数多。

    你可以把用途比较统一的,属于某个模块的一系列参数写到一个类/字典里,传参的时候传单个对象,避免方法调方法还要多次传多个参。
    HackerJax
        8
    HackerJax  
       58 天前
    python 那种不依赖参数顺序且有默认值的可以,PHP 那种强依赖顺序的就不行,
    loryyang
        9
    loryyang  
       58 天前
    主要看是否有冗余,而解决参数多的代码结构问题,可以用参数类来包装
    ychost
        10
    ychost  
       58 天前
    超过 3 个参数就觉得不友好了
    shunia
        11
    shunia  
       58 天前
    主要看是否有文档,有文档都是好设计,没文档你写出花来我用的时候也得骂你。
    Spute
        12
    Spute  
       58 天前   ❤️ 2
    从设计的角度看,参数越多代表依赖的输入越多,意味着耦合性越高,这让相关代码很难修改,这个函数也难被复用。所有如非必要,方法的参数应该做的最少且必要。
    LowBi
        13
    LowBi  
       58 天前
    算坏吧 多了可以选择放到一个对象里
    InkStone
        14
    InkStone  
       58 天前
    参数太多的情况下应该通过结构体传入,正好结构体的 build 还能降低参数构造的复杂度。

    另外基本类型参数太多时,应该通过封装类型做区分,便于使用。

    尽量不要通过 key 为 string 的 map 传参数,每次看到这种东西都想砍人
    junmoxiao
        15
    junmoxiao  
       58 天前
    百分百算差的,这种就该定义结构体
    shawnsh
        16
    shawnsh  
       58 天前 via Android
    好与坏的标准是什么
    NizumaEiji
        17
    NizumaEiji  
       58 天前
    当然不好 且不提参数多了写方法调用的时候很容易出错
    到时候有需要新增个参数 方法签名一变,一改一个不吱声。到时候要么改动上游调用代码 要么自己搞方法重载。
    所以一般超过一定的参数数量都是要求把入参合并到一个对象里。

    我目前见过参数最多的就是 go 的 wire ,不过好在这玩意儿中间的一些代码都是生成出来的,不用手动改,要不头都大了。
    magicfield
        18
    magicfield  
       58 天前
    静态语言方法放一堆参数勉强能接受,但最好还是整个对象。
    动态语言一个方法塞一堆参数,甚至用**kwargs 这种狗屎特性之类,有时候真的想砍人
    Govda
        19
    Govda  
       58 天前
    @HackerJax php8 已经改了,可以跟 Python 一样
    Rache1
        21
    Rache1  
       58 天前
    @HackerJax #8 PHP 8.0 开始也支持像 Py 那样的命名参数了
    yanqing07
        22
    yanqing07  
       58 天前
    @maokg #2 四个还好吧。五个参数我接受不了,IDE 提示要用滚动条了
    adoal
        23
    adoal  
       58 天前
    平行的十几个参数,大概率是没设计好。至少应该按照参数的业务亲密性分组,封装到结构类型里。而且,很有可能,这个接口可以做拆分成更细的接口,或者对调用逻辑做重组设计。
    0xD800
        24
    0xD800  
       58 天前
    不好的设计,应该放到一个结构体里面,否则接口签名变动的时候就抓狂了
    Rorysky
        25
    Rorysky  
       58 天前
    封装在参数对象里
    miaotaizi
        26
    miaotaizi  
       58 天前
    你确定你的场景都会把十几个参数都传吗?

    要不整理一下场景, 把函数重载一下?
    wqhui
        27
    wqhui  
       58 天前
    有时候可以选择用个对象装载所有字段,也可以选择拆出来每个字段传参

    一般情况下,如果对象有 20 个字段,但方法只用到了其中 5 个,我倾向于只传这 5 个用到的字段,而不是整个对象丢进去,主要是为了明确这个方法只会被这几个字段影响运行,而不需要看方法具体逻辑。当然不嫌麻烦的话,为这个方法新建一个传参的对象装这 5 个字段也 ok ,参数多的话建议后者
    Cabana
        28
    Cabana  
       58 天前
    哈哈, 写 Compose 的已经麻木了~
    aolifu
        29
    aolifu  
       58 天前
    之前看过一个 OP 发的帖子,说是他们有的方法一百多个参数,我都惊了 /🤦‍♂️
    Sfilata
        30
    Sfilata  
       58 天前
    我觉得主要看这个方法很多参数是不是有默认值。如果说正常使用,我可以只传一两个参数就可以使用通用功能,需要微调可以传特定的参数来改变行为的话,我觉得就是一个很好的设计。而且我感觉很多 shell 命令就是这么干的。
    UIXX
        31
    UIXX  
       58 天前
    代码结构设计是一种平衡艺术,天平的两端可以是易调用性和易调试性。

    当然可以将几百个参数封装成大众接受数量的结构体,但这同时意味参数层级+1 ,在没有额外针对该结构的接口时,我更倾向于将它展开,除了更清晰的逻辑以及奥卡姆剃刀原则之外,显式地强调其中某些参数的用法也是这样设计的重要原因。
    lonelee
        32
    lonelee  
       58 天前
    java 代码的话是不好的设计,
    kotlin 代码使用默认值+参数名指定完全没问题
    yb2313
        33
    yb2313  
       58 天前
    喜欢多, 那就写**kwargs
    xz410236056
        34
    xz410236056  
       58 天前
    所以现在新语言都有可变参数的设计,调用的时候你想传什么传什么
    xueling
        35
    xueling  
       58 天前
    太多参数不好,完全没有复用性。
    NoOneNoBody
        36
    NoOneNoBody  
       58 天前
    类方法没所谓,通过设计模式或者继承、抽象就能固定某些参数了
    参数太多难点是逻辑,里面估计很多判断
    底层的基础类参数多些能兼顾不同的“状态”,专用的符合业务模型的就继承基础类固定参数
    opengps
        37
    opengps  
       58 天前
    这是按需,没法去界定啥。当然针对具体业务可能有更优的方案
    9c04C5dO01Sw5DNL
        38
    9c04C5dO01Sw5DNL  
       58 天前
    @aolifu 有代码吗,看看
    tairan2006
        39
    tairan2006  
       58 天前
    一般是不好的,不过有默认值的话有时候也可以,主要看还能不能保持常规情况下使用较为简单
    debuggeeker
        40
    debuggeeker  
       58 天前
    参数多不是问题,把每个参数注释写清楚就行
    aolifu
        41
    aolifu  
       58 天前
    @giiiiiithub 没有呢,有机会的话我也想涨涨见识
    blackmirror
        42
    blackmirror  
       58 天前
    外包赶进度赚快钱就好,自己项目写就差
    yemuc
        43
    yemuc  
       58 天前   ❤️ 1
    以前遇到过项目中全部使用 map 传参,想要多少参数就多少参数,整理接口时爽的要死
    dddd1919
        44
    dddd1919  
       58 天前
    方法设计至多一个参数也行,这个参数可以有 n 多属性
    Ericcccccccc
        45
    Ericcccccccc  
       58 天前   ❤️ 1
    多不是问题
    最好是:
    正交
    枚举清晰
    lisongeee
        46
    lisongeee  
       58 天前
    java 没有像 kotlin/python/js 一样的具名参数+默认参数,所以这块参数多起来比较难维护吧

    fun test(name:String, age:Int, x: Int=0, y:Int=0){}

    test("my_name", 18)
    test(name="my_name", age=18)
    test("my_name", 18, y=9)
    xiangyuecn
        47
    xiangyuecn  
       58 天前
    看情况吧:
    自己写的:这风格非常棒
    别人写的:纯属屎山雕花
    facebook47
        48
    facebook47  
       58 天前 via Android
    不好,不说写麻烦,调用也累……确实🈶很多,封装一下最好
    cc666
        49
    cc666  
       57 天前
    按照代码整洁之道的说法,这是不好的设计,一般不超过三个参数,参数多了函数内部的认知复杂度基本也会很高(很多的 if-else ),说简单点就是没封好
    enjoyCoding
        50
    enjoyCoding  
       57 天前
    两三个必传的, 几十个可选的不会觉得是糟糕的涉及. 十几个全是必传的, 那是挺难用的.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1080 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 23:36 · PVG 07:36 · LAX 16:36 · JFK 19:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.