在@amon的建议下,这是一个更单子的答案。这是一个非常精简的版本,您必须接受一些假设:
考虑到这些因素,monad可以转换为流畅的包装器类(尽管您放弃了纯函数式语言所具有的很多灵活性):
public class RepositoryLookup<E> {
private String source;
private E answer;
private Exception exception;
public RepositoryLookup<E>(String source) {
this.source = source;
}
public RepositoryLookup<E> fetchElement() {
if (answer != null) return this;
if (! exception instanceOf NotFoundException) return this;
try {
answer = lookup(source);
}
catch (Exception e) {
exception = e;
}
return this;
}
public RepositoryLookup<E> orFetchSimilarElement() {
if (answer != null) return this;
if (! exception instanceOf NotFoundException) return this;
try {
answer = lookupVariation(source);
}
catch (Exception e) {
exception = e;
}
return this;
}
public RepositoryLookup<E> orFetchParentElement() {
if (answer != null) return this;
if (! exception instanceOf NotFoundException) return this;
try {
answer = lookupParent(source);
}
catch (Exception e) {
exception = e;
}
return this;
}
public boolean failed() {
return exception != null;
}
public Exception getException() {
return exception;
}
public E getAnswer() {
// better to check failed() explicitly ;)
if (this.exception != null) {
throw new IllegalArgumentException(exception);
}
// TODO: add a null check here?
return answer;
}
}
(这不会编译...某些细节未完成以使样本保持较小)
调用看起来像这样:
Repository<String> repository = new Repository<String>(x);
repository.fetchElement().orFetchParentElement().orFetchSimilarElement();
if (repository.failed()) {
throw new IllegalArgumentException(repository.getException());
}
System.err.println("Got " + repository.getAnswer());
请注意,您可以根据需要灵活地组合“获取”操作。当得到答案或未找到的异常时,它将停止。
我做得很快。这不是很正确,但希望传达出这个想法
NotFoundException
的东西,实际上是例外?