Java 代码中业务代码的方法入参是 Function 这种?真的合适吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
lvxiaomao
V2EX    程序员

Java 代码中业务代码的方法入参是 Function 这种?真的合适吗?

  •  1
     
  •   lvxiaomao 2023-08-07 16:35:12 +08:00 3995 次点击
    这是一个创建于 812 天前的主题,其中的信息可能已经有所发展或是发生改变。

    众所周知,java 提供了 Function 、Supplier 等函数式接口。

    在新公司的业务代码中,入参是 Function 这种,我看了一下是因为有 2 个地方调用,这种直接调用一个封装好的方法不行吗? 否则每次看到在方法内调用这 func.get()的时候,还得返回代码入参看看具体的 function 是啥,真的好麻烦呀;

    如果是提供工具类,使用函数式参数我认为是合理的,但是业务代码真的适合这样写吗?

    你们的代码中有这样的入参吗?

    34 条回复    2023-08-11 01:22:06 +08:00
    jorneyr
        1
    jorneyr  
       2023-08-07 16:39:04 +08:00
    Java 不支持函数式编程。
    wetalk
        2
    wetalk  
       2023-08-07 16:39:54 +08:00
    换个思路,把函数式接口当成匿名内部类的对象,就容易接受了
    unco020511
        3
    unco020511  
       2023-08-07 16:40:32 +08:00
    这种很正常吧,反正我们从 java 换到 kotlin 后,很多函数式参数
    lvxiaomao
        4
    lvxiaomao  
    OP
       2023-08-07 16:50:12 +08:00
    @wetalk #2 但是读起来真的麻烦,读到方法一半,然后返回去看看这个 function 是啥
    lvxiaomao
        5
    lvxiaomao  
    OP
       2023-08-07 16:50:59 +08:00
    @unco020511 #3 就是读起来费劲
    mgzu
        6
    mgzu  
       2023-08-07 16:58:41 +08:00
    有没有可能是参数名命名的问题呢,func 修改为更具体的命名,如:getXXX ,doXXX ,达到见名知意的效果
    Oktfolio
        7
    Oktfolio  
       2023-08-07 17:01:15 +08:00
    用啊,为什么不用?
    TWorldIsNButThis
        8
    TWorldIsNButThis  
       2023-08-07 17:02:30 +08:00 via iPhone
    再正常不过了
    TWorldIsNButThis
        9
    TWorldIsNButThis  
       2023-08-07 17:05:10 +08:00 via iPhone   1
    另外多说一嘴,函数入参是最简单的 ioc 方式
    adoal
        10
    adoal  
       2023-08-07 17:05:15 +08:00   3
    不如再换个公司,还在用 JDK 1.6 维护遗留系统的
    xiaoHuaJia
        11
    xiaoHuaJia  
       2023-08-07 17:06:44 +08:00
    用 贼好用
    issakchill
        12
    issakchill  
       2023-08-07 17:12:00 +08:00
    挺好用的啊
    hepin1989
        13
    hepin1989  
       2023-08-07 17:15:43 +08:00
    挺好的,合适,不过可以看看团队的程度。
    luzemin
        14
    luzemin  
       2023-08-07 17:18:00 +08:00
    挺好用的,对标 C#中的委托,把函数当参数传递
    jiangteng
        15
    jiangteng  
       2023-08-07 17:18:58 +08:00
    都提供了为什么不用,确实能写起来更方便啊,特别是针对逻辑半截需要做不同处理的
    chendy
        16
    chendy  
       2023-08-07 17:24:54 +08:00   1
    有没有一种可能这玩意叫 策略模式
    看着费劲可能是:
    1. 抽象不对导致必须关注实现细节
    2. 修改维护需要必须看实现细节
    反正也就一个 find usage 的事,相比之下还是 一堆 XXService 接口对一个 XXServiceImpl 的 写法最蛋疼…
    gogo789
        17
    gogo789  
       2023-08-07 17:35:42 +08:00
    在业务代码里面有,感觉确实不太合适,业务代码的特点就是通用性比较差。举例来说,一个 Service 的入参,根据不同的 Function 执行不同的逻辑,以后维护、测试也是个问题,建议还是拆分成两个不同的方法。
    Rache1
        18
    Rache1  
       2023-08-07 17:38:14 +08:00
    @lvxiaomao #4 Intellij 系列的 IDE ,你可以选中方法后按下 Ctrl+SHIF+I(大写字母 i),可以有一个小窗来显示这个方法的实现。
    tedzhou1221
        19
    tedzhou1221  
       2023-08-07 17:41:30 +08:00
    正在学习函数式编程,按理解是函数式编程 易于理解、对测试友好。
    tedzhou1221
        20
    tedzhou1221  
       2023-08-07 17:43:21 +08:00
    看了 dubbo 源码,服务注册功能。不少地方都用了函数编程。
    nothingistrue
        21
    nothingistrue  
       2023-08-07 19:03:06 +08:00 via Android
    对于使用函数式接口作为参数的方法,它期望的是即时生成的匿名函数,而不是事先做好的公共组件。这种情况下,写下 func.get()的时候,它连 func 是谁都不知道,怎么可能让去找原始 Function 的代码。

    函数式接口,是给你写即时匿名 Lamda 函数,不是用来定义公共函数的。你们公司这行为,明显是用错了。
    jimrok
        22
    jimrok  
       2023-08-07 19:13:20 +08:00
    设计用 Function 的场景,首先要站在使用者的角度看,如果这个业务调用频率非常高,业务逻辑不固定,如果用 Interface 去实现,非常繁琐,那么就设计成 Function 会比较好,让调用者走写 lamda 会舒服很多。否则别这样设计。
    nothingistrue
        23
    nothingistrue  
       2023-08-07 19:15:58 +08:00 via Android
    友情提示:常规的函数式接口,只能用 Lamba ,或者匿名内部类初始化,意味着该类型的变量,只能是方法内部的局部变量。不用违反常理的黑科技,压根就不能复用 Function 。
    ljsh093
        24
    ljsh093  
       2023-08-07 19:49:19 +08:00
    @adoal #10 目前在用 8 104
    zhouhu
        25
    zhouhu  
       2023-08-07 19:49:38 +08:00
    你只需要关心这个函数入参和出参
    netabare
        26
    netabare  
       2023-08-07 21:37:20 +08:00 via Android   1
    函数入参传个函数进来不是最基本依赖注入吗。异步框架的事件驱动和回调也大量使用了函数式接口,不知道这有什么不合适的。
    e3c78a97e0f8
        27
    e3c78a97e0f8  
       2023-08-08 00:00:38 +08:00   2
    @lvxiaomao 按理说,如果 Function 是传进来的参数,那意味着这个 method 和 Function 的具体实现无关。如果你要看具体的 Function 才明白干什么,那要么是你理解有问题,要么是这个 method 抽象得不对。
    dqzcwxb
        28
    dqzcwxb  
       2023-08-08 09:09:17 +08:00
    建议去看看 Stream 实现
    yoyolichen
        29
    yoyolichen  
       2023-08-08 09:54:24 +08:00
    stream 里不全是这玩意么 正常吧
    lvxiaomao
        30
    lvxiaomao  
    OP
       2023-08-08 10:41:04 +08:00
    @netabare #26 工具类的这么写没问题,就是业务代码感觉怪怪的。
    mmdsun
        31
    mmdsun  
       2023-08-08 14:03:01 +08:00
    看代码才知道设计是否合理。
    通用来讲,这叫行为参数化(类似于策略设计模式)。

    拿 GPT 举例说明一下:

    """
    函数编程中的行为参数化是指将一个行为(或功能)作为参数传递给函数,以便在不同的上下文中执行不同的操作。这种方式可以使函数更加通用和灵活,可以根据传入的不同行为参数来实现不同的行为,而不必每次都定义新的函数。

    在函数编程语言或支持函数式编程风格的编程语言中,行为参数化通常通过函数、Lambda 表达式、函数接口( Functional Interface )等实现。

    // 使用不同的条件来筛选元素
    filter(numbers, n -> n % 2 == 0); // 筛选偶数
    filter(numbers, n -> n > 5); // 筛选大于 5 的数
    """
    lvxiaomao
        32
    lvxiaomao  
    OP
       2023-08-08 15:02:00 +08:00
    @mmdsun #31 是的,这个意思明白,但是代码中就是把这个 lambda ,当做公共方法来用的;

    就是该函数入参的 function ,多处调用传入是一样的,而不是不同的; 所以感觉不合理
    lavvrence
        33
    lavvrence  
       2023-08-08 16:44:19 +08:00
    你写几次 Node.js 就习惯了。
    xingchenxf
        34
    xingchenxf  
       2023-08-11 01:22:06 +08:00 via Android
    不合理。
    当代码质量高的时候,能看名达意,并且这部分代码不容易出问题,不会改动的时候,这样做合适。
    但是业务代码往往质量不高,且频繁变动。这种情况下,代码用的技巧越多,最后变成一坨屎的概率越大。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3668 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 10:27 PVG 18:27 LAX 03:27 JFK 06:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86