實際上,我看到了許多可行的選擇,每個選項都有自己的優勢/弱點。
返回時,有沒有更多的書,由埃德溫·巴克描述的定點對象:
public Book getBook() {
public static Book NO_BOOK = new Book();
if(books.empty()) {
return NO_BOOK;
}
...
}
book = shelf.getBook();
if(Book.NO_BOOK.equals(book)) {
// there were no books
}
返回NULL如果沒有更多的書,因爲你提到你不想做
public Book getBook() {
if(books.empty()) {
return null;
}
...
}
book = shelf.getBook();
if(book == null) {
// there were no books
}
拋出一個異常時,有沒有留下的書籍,並實現hasMoreBooks。
public boolean hasMoreBooks() {
return (! books.empty());
}
public Book getBook() {
if(books.empty()) {
throw new IllegalStateException("no more books");
}
...
}
if(shelf.hasMoreBooks()) {
book = shelf.getBook();
// you know it's a valid book here
}
在其他語言中實現一個也許類型包裝按哈斯克爾。這種類型的對象表示「可能是書,或可能沒有」的東西。然後調用者負責檢查它是否是有效的書。對於爲這種類型的操作(模式匹配等)提供良好支持並且不支持null的語言(null是魔鬼;),這是一個很好的解決方案。對於Java,我傾向於認爲它是過度的。
至於「揭露實施」,我不認爲這是不合理的,用戶知道書架可以「出書」,並認爲這是無法從它那裏得到一本書,如果是這樣的話。
編輯:我會添加一個與這個問題沒有直接關係的註釋,但值得一提。在沒有圖書的情況下拋出異常(並實現hasMoreBooks)的好處之一是,你並不總是需要檢查是否有書。
舉例來說,如果你有一個緊密的循環,通過書籍進行迭代,並有一本書的次數遠遠多於沒有一個,你可以做類似如下:
try {
while(true) {
book = shelf.getBook();
...
}
} catch(IllegalStateException ex) {
// no more books
}
要公平,在大多數情況下,這並不是那麼有用......但如果您擔心必須致電hasMoreBooks的性能成本,並且您知道您很少擁有更多書籍,則上述內容可能會很方便。
好吧,如果你不返回NULL,你可以返回一個代表書架缺少書本的「虛擬」書,也可能包含一個叫做isDummyBookBecauseShelfIsEmptyAndIDontWantToReturnNull的指示器,所以你知道這本書是你得到的真的不是一本書......但是你*有*返回*某物* ...我想你在試圖從它那裏拿一本書之前檢查貨架是不是空的,但那只是我。 – FrustratedWithFormsDesigner 2010-10-01 17:52:32
當你不習慣使用null時,返回null看起來很難看。空有效意味着「沒有」,因此,在您適應返回null之後,您會意識到,當調用getBook(...)時,空的書架應該不會返回任何內容。 – 2010-10-01 18:35:01
如果這是Scala或Haskell,您可以分別返回'Option'或'Maybe Book',以表明不存在任何書。 –
2010-10-01 18:41:32