@ Amon'un önerisine göre, daha monadik bir cevap. Birkaç varsayımı kabul etmeniz gereken çok haşlanmış bir versiyon:
"birim" veya "dönüş" işlevi sınıf yapıcısıdır
"bağlama" işlemi derleme zamanında gerçekleşir, dolayısıyla çağrıdan gizlenir
"action" işlevleri de derleme zamanında sınıfa bağlıdır
Her ne kadar sınıf genel ve herhangi bir keyfi E sınıfı sararsa da, bu durumda aslında aşırıya kaçan şey olduğunu düşünüyorum. Ama bunu yapabileceğin bir örnek olarak bıraktım.
Bu düşüncelerle, monad akıcı bir sarmalayıcı sınıfına dönüşür (tamamen işlevsel bir dilde alacağınız esnekliğin çoğundan vazgeçmenize rağmen):
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;
}
}
(bu derlenmeyecektir ... numuneyi küçük tutmak için bazı ayrıntılar tamamlanmamıştır)
Ve çağırma şöyle görünecektir:
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());
"Getirme" işlemlerini istediğiniz gibi oluşturma esnekliğine sahip olduğunuzu unutmayın. Bulunamayan bir cevap veya istisna aldığında duracaktır.
Bunu çok hızlı yaptım; bu doğru değil, ama umarım fikri iletir
NotFoundException
aslında olağanüstü bir şey?