9

我正在为我们创建的 API 编写演示代码,但我一直遇到同样的问题,我一遍又一遍地重复自己,令人作呕。我痛苦地意识到 Java 计划添加闭包,但我现在无法访问它们。以下是在所有地方重复的内容,我只想把它装进它自己的小角落:

public BarObj Foo(Double..._input){
    try{
        //things that vary per function
        //but everything else...
    } catch(NullException _null){
        m_Logger.error("Null error exception caught in Blah::Foo");

        return null;
    } catch(Exception ex){
        m_Logger.error( ex.getMessage() );

        return null;
    }
}

关于我认为解决此问题的唯一方法是将 a 传递给Method一个带有 try-catch 逻辑的函数,并将其全部包装在另一个函数中,如下所示:

public BarObj MyFunc(Double..._input){
    return compose("MyLogic",_input);
}

private BarObj MyLogic(Double..._input) 
    throws Exception{
    //stuff
}

但它看起来很丑,并且带有很多样板。有没有更简单的方法在 Java 中编写函数?

4

5 回答 5

8

在 Java 中这是非常困难的,因为没有对函数的一流支持(不像 clojure 或 scala 可能还有其他)。

但是,您可以将操作封装在一个对象中:

interface Function<R, T> {

     R call(T... input);
}

然后重构Foo为:

static <R, T> R runFunction(Function<R, T> function, T ... input){
    try{
       return function.call(input);
    } catch(NullPointerException _null){
       m_Logger.error("Null error exception caught in Blah::Foo");
       return null;
    } catch(Exception ex){
       m_Logger.error( ex.getMessage() );
       return null;
    }
}

测试用例:

class SumDoubles implements Function<Double, Double> {

    @Override
    public Double call(Double... input) {
        Double sum = 0.0;

        for (Double d : input) {
            sum += d;
        }

        return sum;
    }
}

@Test
public void sum() {
    Double sum = runFunction(new SumDoubles(), 1.0, 2.0, 3.0);
    assertThat(sum, is(6.0));
}
于 2010-02-05T14:47:52.350 回答
2

试试lambdaj。它允许以一种非常轻便易读的方式向 java 添加一些 FP。特别是在这个closure wiki页面中,您可以找到一个与您尝试实现的非常相似的示例,

于 2010-02-05T14:44:44.007 回答
0

这显然是您的要求,但在我使用的大多数 API 演示中,我更喜欢顶部的较长格式。在查看代码后,我通常会复制和粘贴来验证 API 是否像我认为的那样工作,然后从那里修改它。更改格式以隐藏一些重复部分绝对是您想要为 OO 开发做的事情,但我认为这种演示代码是“干净代码之神”会理解的 :-)。

于 2010-02-05T14:46:40.263 回答
0

在 java 中没有办法做到这一点,但如果可能的话,请尝试使用 groovy。您可以进行类似包装的另一个选项是使用方面。见方面j

于 2010-02-05T14:47:27.263 回答
0

我了解到在 Java 中完成此操作的方式是创建一个具有一种方法的接口。在您的代码中,您使用实现该接口的类。

于 2010-02-05T14:47:33.927 回答