Вопрос

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

Это было полезно?

Решение

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

Другие советы

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

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

В java нет способа сделать это, но попробуйте использовать groovy, если это возможно для вас.Другой вариант, при котором вы можете создать аналогичную оболочку, - это использование aspect .видишь аспект j.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top