Theo đề nghị của @ amon, đây là một câu trả lời đơn điệu hơn. Đây là một phiên bản rất sôi nổi, nơi bạn phải chấp nhận một vài giả định:
hàm "unit" hoặc "return" là hàm tạo của lớp
hoạt động "liên kết" xảy ra vào thời gian biên dịch, vì vậy nó bị ẩn khỏi lệnh gọi
các hàm "hành động" cũng được liên kết với lớp trong thời gian biên dịch
mặc dù lớp này là chung chung và bao bọc bất kỳ lớp E tùy ý, tôi nghĩ rằng điều đó thực sự quá mức trong trường hợp này. Nhưng tôi đã để nó theo cách đó như một ví dụ về những gì bạn có thể làm.
Với những cân nhắc đó, đơn nguyên chuyển thành một lớp bao bọc trôi chảy (mặc dù bạn đang từ bỏ rất nhiều sự linh hoạt mà bạn có được bằng một ngôn ngữ hoàn toàn có chức năng):
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;
}
}
(điều này sẽ không được biên dịch ... một số chi tiết nhất định còn dang dở để giữ cho mẫu nhỏ)
Và lời cầu khẩn sẽ như thế này:
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());
Lưu ý rằng bạn có thể linh hoạt soạn các thao tác "tìm nạp" theo ý muốn. Nó sẽ dừng lại khi nhận được câu trả lời hoặc một ngoại lệ khác ngoài không tìm thấy.
Tôi đã làm điều này thực sự nhanh chóng; nó không hoàn toàn đúng, nhưng hy vọng truyền đạt ý tưởng
NotFoundException
một cái gì đó thực sự đặc biệt?