Как я могу объединить функциональные вызовы в Java? - PullRequest
6 голосов
/ 07 января 2020

У меня есть два одинаковых фрагмента кода:

void task1() {
    init();
    while(someCondition) {
      doSomething();
    }
    shutdown();
  }
void task2() {
    while(someCondition) {
      init();
      doSomething();
      shutdown();
    }
  }

Я бы хотел избежать дублирования кода, и я подумал, что это можно сделать с помощью функционального подхода. Я хочу поместить вызовы l oop и init / shutdown в отдельные функции, а затем объединить их вызовы (не интерфейс функции Java 8, больше псевдокод):

Function setup(Function f){
    init();
    f();
    shutdown();
}
Function loop(Function f){
    while(someCondition) {
      f();
    }
}

Тогда Я хочу связать их так:

void task1() {
   setup(loop(doSomething));
 }
void task2() {
    loop(setup(doSomething));
  }

Я думал о compose / andThen в интерфейсе функций Java, но они не подходят, потому что они передают только возвращаемое значение одной функции к следующему. У кого-нибудь есть идеи, как это сделать с Java 8 или с другим подходом?

1 Ответ

11 голосов
/ 07 января 2020

Вы действительно можете сделать это. Вам нужно Runnable, а не Function, поскольку ваши методы не принимают параметров и не возвращают значений. Если ваши методы имеют другую сигнатуру, вам нужно использовать другой тип.

public static void init() { ... }
public static void doSomething() { ... }
public static void shutdown() { ... }

public static Runnable setup(Runnable r) {
    return () -> {
        init();
        r.run();
        shutdown();
    };
}

public static Runnable loop(Runnable r) {
    return () -> {
        while (someCondition) {
            r.run();
        }
    };
}

// I used "Main" here because this in a class called Main. Replace "Main" with the name of your class
public static void task1() {
    setup(loop(Main::doSomething)).run();
}

public static void task2() {
    loop(setup(Main::doSomething)).run();
}

Следует также отметить, что, хотя на взгляд функционального программиста первый код может выглядеть «дублированным», до Java программисты, первый код очень хорош как есть. Переписать его таким образом может быть более запутанным для людей, которые не привыкли к функциональному стилю.

...