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

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

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

    众所周知,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 ,多处调用传入是一样的,而不是不同的; 所以感觉不合理
    jaylee4869
        33
    jaylee4869  
       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   ·   实用小工具   ·   2798 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:49 · PVG 22:49 · LAX 06:49 · JFK 09:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.