用 Java 编写函数?

发布于 2024-08-20 05:29:24 字数 802 浏览 11 评论 0原文

我正在为我们创建的 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;
    }
}

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

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

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

但它看起来很丑并且带有很多样板。在 Java 中是否有更简单的方法来组合函数?

I'm writing demo code for an API we've created and I keep running into the same problem where I'm repeating myself, over and over ad nauseum. I am painfully aware that Java is scheduled to have closures added but I don't have access to them now. Here is what is repeated all over the place that I'd like to just box into it's own little corner:

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;
    }
}

About the only way I've thought to go around this is by passing a Method into a function which carries with it the try-catch logic and wrapping it all up in another function like so:

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

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

but it looks ugly and carries with it a lot of boilerplate. Is there an easier way to compose functions in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅暮の光 2024-08-27 05:29:24

在 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;
    }
}

testcase:

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));
}

in Java this is very difficult since there is no first class support for functions (unlike clojure or scala and probably other).

However, you can encapsulate the operation in an object:

interface Function<R, T> {

     R call(T... input);
}

then refactor Foo as:

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;
    }
}

testcase:

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));
}
小傻瓜 2024-08-27 05:29:24

尝试 lambdaj。它允许以一种相当轻量且可读的方式向 java 添加一些 FP。
特别是在这个 closure wiki 页面中,您可以找到一个与以下内容非常相似的示例你正在努力实现,

Try lambdaj. It allows to add a bit of FP to java in a quite light and readable way.
In particular in this closure wiki page you can find an example very similar to what you are trying to achieve,

遮了一弯 2024-08-27 05:29:24

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

This is obviously your call, but with most API demos I've used I prefer the longer format that you have at the top. After I look over the code I typically do copy-and-paste to verify the API works like I think it does then modify it from there. Changing the format to hide some of the repetative pieces is definately what you want to do for OO development but I think that this kinda demo code is something that the 'clean code gods' would understand :-) .

莫多说 2024-08-27 05:29:24

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

There is no way of doing this in java, but try using groovy if it is possible for you. The other option you can have similar wrapping is using aspect. see aspectj.

苄①跕圉湢 2024-08-27 05:29:24

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

I learned the way this is done in Java is to create an interface that has one method. In your code you use classes implementing that interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文