我将下面的代码实现为一个很好的通用解决方案,通过尝试一个接一个的策略来获取内容,直到我找到某些内容或者如果不成功则返回空。
import java.util.Optional;
import java.util.function.Supplier;
public class StrategyEvaluator {
/**
* Evaluate supplier stategies that produce Optionals until one returns something.
* @param suppliers
* @return the optional provided by the first successful supplier or Optional.empty()
*/
@SafeVarargs
public static <T> Optional<T> evaluate(Supplier<Optional<T>>...suppliers) {
for(Supplier<Optional<T>>s: suppliers) {
Optional<T> maybe = s.get();
if(maybe.isPresent()) {
return maybe;
}
}
return Optional.empty();
}
}
这是我如何使用它的一个例子:
public Optional<Contact> getContactForOwner(boolean cached, String contactId, String ownerId, boolean followLinks) {
return StrategyEvaluator.evaluate(
() -> getFromDao(cached, contactId, ownerId, followLinks),
() -> getUserProfileContact(cached, contactId),
() -> searchContactByIdAndHandles(contactId, ownerId)
);
}
所以,这很好用,似乎做了它需要做的事情,并且它比嵌套的更好,如果它被替换了。但是,我想知道我是不是在这里重新发明轮子以及是否有更好的方法来做同样的事情。另外,我想知道这种方法在开销或泛型怪异方面是否有任何缺点?例如,Varargs和泛型相互之间并没有很好地发挥作用,因此@SafeVarargs。
我试图避免使用更加苛刻的解决方案,例如拥有一个包含供应商列表的策略构建器以及我需要分配给我然后重用的实例的评估方法(即传统的策略模式) )。我的目标是在使用它时几行代码之间进行权衡,而不是太多开销。这至少看起来很整洁,它确实起到了作用。