Составление функций в Java? - PullRequest
9 голосов
/ 05 февраля 2010

Я пишу демонстрационный код для 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?

Ответы [ 5 ]

8 голосов
/ 05 февраля 2010

в 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));
}
2 голосов
/ 05 февраля 2010

Попробуйте лямбдай . Это позволяет добавить немного FP в Java довольно легким и читабельным способом. В частности, на этой закрывающей вики-странице вы можете найти пример, очень похожий на то, чего вы пытаетесь достичь,

0 голосов
/ 05 февраля 2010

Я узнал, как это делается в Java, это создать интерфейс с одним методом. В вашем коде вы используете классы, реализующие этот интерфейс.

0 голосов
/ 05 февраля 2010

Нет никакого способа сделать это в Java, но попробуйте использовать groovy, если это возможно для вас. Другой вариант, который вы можете иметь подобную упаковку, использует аспект. см aspectj .

0 голосов
/ 05 февраля 2010

Это, очевидно, ваш вызов, но с большинством демонстрационных версий API, которые я использовал, я предпочитаю более длинный формат, который у вас вверху. После просмотра кода я обычно копирую и вставляю, чтобы убедиться, что API работает так, как мне кажется, и затем модифицирует его. Изменение формата, чтобы скрыть некоторые повторяющиеся фрагменты, безусловно, то, что вы хотите сделать для разработки ОО, но я думаю, что этот своего рода демонстрационный код - это то, что «боги чистого кода» поняли бы :-).

...