Есть ли объект, способный связывать последовательные вызовы методов - PullRequest
1 голос
/ 07 августа 2020

У меня есть несколько методов со следующим шаблоном:

int status = method0();
if(status = success){
  status = method1();
}
if(status = success){
  status = method2();
}
if(status = success){
  status = method3();
}
if(status = success){
  status = method4();
}
return status

И я хотел бы сделать это более читабельным. Я представляю себе что-то вроде этого:

final CommandPipe pipe = new CommandPipe();
status = pipe.next(() -> method0(arg0))
              .next(() -> method1(arg1))
              .next(() -> method2(arg2))
              .next(() -> method3(arg3))
              .next(() -> method4(arg4))
              .getResult();
return status; 

Есть ли объект, делающий это в Java 8?

Ответы [ 4 ]

2 голосов
/ 07 августа 2020

Используйте List<IntSupplier> и a для l oop:

int method(List<IntSupplier> list) {
  int status = success;
  for (Iterator<IntSupplier> it = list.iterator(); status == success && it.hasNext();) {
    status = it.next().get();
  }
  return status;
}

Вызвать как:

int status = method(List.of(
    () -> method0(arg0),
    () -> method1(arg1) /* etc */));

(Конечно, List.of - это метод Java 9 . Составьте свой список так, как вам нравится).

Ваш CommandPipe класс было бы довольно легко написать:

class CommandPipe {
  int status = success;

  CommandPipe next(IntSupplier supplier) {
    if (status == success) {
      status = supplier.get();
    }
    return this;
  }

  int getResult() { return status; }
}

Вызов, как вы написали в вопросе.

2 голосов
/ 07 августа 2020

Думаю, проще всего реализовать такой тип самостоятельно, например:

public class CommandPipe<T> {
    private Predicate<T> predicate;
    private T lastResult = null;
    private boolean firstInvotion = true;
    public CommandPipe(Predicate<T> predicate) {
      this.predicate = predicate;
    }

    public CommandPipe next(Supplier<T> supplier) {
        boolean doStep;

        if (firstInvotion) {
            firstInvotion = false;
            doStep = true;
        } else {
            doStep = predicate.test(lastResult);
        }

        if (doStep) {
            lastResult = supplier.get();
        } else {
            // error handling
        }

        return this;
    }

    public T getResult() {
        return lastResult;
    }
}
2 голосов
/ 07 августа 2020

На данный момент нет. Поскольку его рамки вашего бизнес-кейса не предоставляют таких вещей. Вы должны сконструировать сами, иначе вы можете использовать CompletableFuture.supplyAsyn c, а затем последовательно применить методы для лучшего использования ресурсов потоками.

0 голосов
/ 07 августа 2020

Вы можете определить метод stati c с помощью таких переменных.

public static int pipe(IntSupplier... methods) {
    int success = 0;
    int status = success;
    for (IntSupplier m : methods) {
        status = m.getAsInt();
        if (status != success)
            break;
    }
    return status;
}

и

int status = pipe(
    () -> method0(arg0),
    () -> method1(arg0),
    () -> method2(arg0),
    () -> method3(arg0),
    () -> method4(arg0));
...