好的,标题可能很难理解。我没有找到正确的东西。 所以,基本上我使用Java 8函数来创建一个Retryable API。我想要简单地实现这些接口,所以我在Retryable接口的每个实现中创建了一个of(...)
方法,我们可以使用lambda表达式,而不是手动创建匿名类。为内部子接口创建一个“默认构造函数”
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public interface Retryable<T, R> extends Function<T, R>{
void retrying(Exception e);
void skipping(Exception e);
int trials();
@Override
default R apply(T t) {
int trial = 0;
while (true) {
trial++;
try {
return action(t);
} catch (Exception e) {
if (trial < trials()) {
retrying(e);
} else {
skipping(e);
return null;
}
}
}
}
R action(T input) throws Exception;
interface RunnableRetryable extends Retryable<Void, Void> {
static RunnableRetryable of(Consumer<Exception> retrying, Consumer<Exception> skipping, int trials, CheckedRunnable runnable) {
return new RunnableRetryable() {
@Override
public void retrying(Exception e) {
retrying.accept(e);
}
@Override
public void skipping(Exception e) {
skipping.accept(e);
}
@Override
public int trials() {
return trials;
}
@Override
public Void action(Void v) throws Exception {
runnable.tryRun();
return null;
}
};
}
@FunctionalInterface
interface CheckedRunnable extends Runnable {
void tryRun() throws Exception;
@Override
default void run() {
try {
tryRun();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
interface ConsumerRetryable<T> extends Retryable<T, Void> {
static <T> ConsumerRetryable of(Consumer<Exception> retrying, Consumer<Exception> skipping, int trials, CheckedConsumer<T> consumer) {
return new ConsumerRetryable<T>() {
@Override
public void retrying(Exception e) {
retrying.accept(e);
}
@Override
public void skipping(Exception e) {
skipping.accept(e);
}
@Override
public int trials() {
return trials;
}
@Override
public Void action(T t) throws Exception {
consumer.tryAccept(t);
return null;
}
};
}
@FunctionalInterface
interface CheckedConsumer<T> extends Consumer<T> {
void tryAccept(T t) throws Exception;
@Override
default void accept(T t) {
try {
tryAccept(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
interface SupplierRetryable<T> extends Retryable<Void, T> {
static <T> SupplierRetryable of(Consumer<Exception> retrying, Consumer<Exception> skipping, int trials, CheckedSupplier<T> supplier) {
return new SupplierRetryable<T>() {
@Override
public void retrying(Exception e) {
retrying.accept(e);
}
@Override
public void skipping(Exception e) {
skipping.accept(e);
}
@Override
public int trials() {
return trials;
}
@Override
public T action(Void v) throws Exception {
return supplier.tryGet();
}
};
}
@FunctionalInterface
interface CheckedSupplier<T> extends Supplier<T> {
T tryGet() throws Exception;
@Override
default T get() {
try {
return tryGet();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
interface FunctionRetryable<T, R> extends Retryable<T, R> {
static <T, R> FunctionRetryable of(Consumer<Exception> retrying, Consumer<Exception> skipping, int trials, CheckedFunction<T, R> function) {
return new FunctionRetryable<T, R>() {
@Override
public void retrying(Exception e) {
retrying.accept(e);
}
@Override
public void skipping(Exception e) {
skipping.accept(e);
}
@Override
public int trials() {
return trials;
}
@Override
public R action(T t) throws Exception {
return function.tryApply(t);
}
};
}
@FunctionalInterface
interface CheckedFunction<T, R> extends Function<T, R> {
R tryApply(T t) throws Exception;
@Override
default R apply(T t) {
try {
return tryApply(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
}
但正如你所看到的,有一个在每个of(...)
方法有很多重复的代码。我可以在Retryable接口中创建一种“构造函数”(这不是正确的词,因为接口不能有构造函数),但我不知道如何。有人有想法吗?
我没有看到这些冗余内部接口存在的理由。对于不同参数化的'Retryable',您只有多个工厂方法。 – Holger