我想创建一个类,该类可以运行一种方法,直到满足有关返回值的条件为止。
它应该看起来像这样
methodPoller.poll(pollDurationSec, pollIntervalMillis) .method(dog.bark()) .until(dog -> dog.bark().equals("Woof")) .execute();
我的方法轮询器看起来像这样()//在GuiSim回答之后
public class MethodPoller { Duration pollDurationSec; int pollIntervalMillis; public MethodPoller() { } public MethodPoller poll(Duration pollDurationSec, int pollIntervalMillis) { this.pollDurationSec = pollDurationSec; this.pollIntervalMillis = pollIntervalMillis; return this; } public <T> MethodPoller method(Supplier<T> supplier) { return this; } public <T> MethodPoller until(Predicate<T> predicate) { return this; } }
但是我很难从这里开始。 在满足条件之前,如何实现对通用方法的重试? 谢谢。
是的,这可以在Java 7中轻松完成,甚至可以使用Java 8进行更清洁的操作。
method方法的参数应为java.util.function.Supplier<T>,until方法的参数应为java.util.function.Predicate<T>。
method
java.util.function.Supplier<T>
until
java.util.function.Predicate<T>
然后,您可以使用方法引用或lambda表达式来创建Poller,如下所示:
myMethodPoller.poll(pollDurationInteger, intervalInMillisecond) .method(payment::getStatus) .until (paymentStatus -> paymentStatus.getValue().equals("COMPLETED")) .execute();
附带说明一下,如果您要使用Java 8,建议您使用java.time.Duration而不是整数来表示轮询持续时间和间隔。
java.time.Duration
我还建议您查看https://github.com/rholder/guava- retrying,这是您可能会使用的库。如果没有,这可能是您的API的良好灵感,因为它具有出色的流畅API。
编辑:对问题的更新之后,这是一个简单的实现。我剩下一些部分供您完成TODO。
import java.time.Duration; import java.util.function.Predicate; import java.util.function.Supplier; public class MethodPoller<T> { Duration pollDurationSec; int pollIntervalMillis; private Supplier<T> pollMethod = null; private Predicate<T> pollResultPredicate = null; public MethodPoller() { } public MethodPoller<T> poll(Duration pollDurationSec, int pollIntervalMillis) { this.pollDurationSec = pollDurationSec; this.pollIntervalMillis = pollIntervalMillis; return this; } public MethodPoller<T> method(Supplier<T> supplier) { pollMethod = supplier; return this; } public MethodPoller<T> until(Predicate<T> predicate) { pollResultPredicate = predicate; return this; } public T execute() { // TODO: Validate that poll, method and until have been called. T result = null; boolean pollSucceeded = false; // TODO: Add check on poll duration // TODO: Use poll interval while (!pollSucceeded) { result = pollMethod.get(); pollSucceeded = pollResultPredicate.test(result); } return result; } }
样品使用:
import static org.junit.Assert.assertTrue; import java.util.UUID; import org.junit.Test; public class MethodPollerTest { @Test public void test() { MethodPoller<String> poller = new MethodPoller<>(); String uuidThatStartsWithOneTwoThree = poller.method(() -> UUID.randomUUID().toString()) .until(s -> s.startsWith("123")) .execute(); assertTrue(uuidThatStartsWithOneTwoThree.startsWith("123")); System.out.println(uuidThatStartsWithOneTwoThree); } }