2010-02-05 103 views
9

我正在为我们创建的API编写演示代码,并且我一直在遇到同样的问题,在那里我重复自己,一遍又一遍的广告恶心。我很痛苦地意识到Java计划添加闭包,但我现在无法访问它们。这里是重复遍,我想只是框到它自己的小角落的地方:在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中的函数?

+0

我觉得有些提议Java中的闭包扩展看起来更丑陋。 – DerMike 2010-02-05 17:09:11

回答

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

那么你会建议这些在更大的'Foo'类中作为私人类吗?我认为这是一个相当好的问题分离。顺便说一句,我喜欢斯卡拉。 – wheaties 2010-02-05 14:51:37

2

尝试lambdaj。它允许以相当轻便和可读的方式向Java中添加一些FP。 特别是在这closure wiki page,你可以找到一个非常相似的例子,你试图实现,

0

这显然是你的电话,但对于我用过的大多数API演示,我更喜欢你有更长的格式最佳。在我查看代码后,我通常会复制并粘贴以验证API的工作方式,就像我认为的那样,然后从那里修改它。改变格式来隐藏一些重复的部分肯定是你想为OO开发做什么,但我认为这种演示代码是'干净的代码之神'会理解的:-)。

0

在java中没有办法做到这一点,但尝试使用groovy,如果它是可能的你。另一种选择你可以有类似的包装使用方面。见aspectj

0

我在Java中学到了这样做的方式,就是创建一个有一个方法的接口。在你的代码中,你使用了实现这个接口的类。