Создание функций на Java?
-
18-09-2019 - |
Вопрос
Я пишу демонстрационный код для созданного нами 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, заключается в создании интерфейса, который имеет один метод.В вашем коде вы используете классы, реализующие этот интерфейс.