2017-01-09 55 views
1

我試圖對API返回結果分頁格式的服務調用,並希望對此迭代器的設計模式的建議。與Java分頁迭代器的設計模式

什麼我到現在爲止是這樣的

public class CustomIterator implements Iterator<Type> { 

private List<Result> results; 
private Service service; 

private int index; 
private int paginatedResultSize; 
private int totalResultsSize; 

public CustomIterator(Service service) { 
    this.service = service; 
    this.index = 0; 
    this.results = getResults(index); 
    this.totalResultsSize = this.results.totalResultsSize(); 
} 

@Override 
public boolean hasNext() { 
    if (index < totalResultsSize) 
    return true; 
    return false; 
} 

@Override 
public Type next() { 

    if(index == paginatedResultSize) { 
    getResults(index); 
    } 

    return results[index++]; 

} 

private List<Result> getResults(index) throws Exception { 
    this.results = service.makeServiceCall(index); 
    this.paginatedResultSize = this.results.size(); 
    return this.results; 
} 

} 

現在,我明白了迭代器的目的通常是爲了只是重複,但我也希望整個分頁封裝到一個單獨的區域,從而我的客戶端類可以在類上調用.next()並獲取所有值,而無需瞭解內部分頁詳細信息。有沒有乾淨的模式來完成這項工作?

有了這個我遇到的第一個問題是服務調用拋出一個檢查異常,next()顯然不是。

我在互聯網上注意到的一些選項是有這個拋出一個RunTimeException,我寧願只做最後的手段,因爲我喜歡檢查服務調用異常。我的直覺是,服務調用應完全在單獨的一個層次上完成,但我不確定迭代器如何與那個分頁一起工作。任何建議/鏈接表示讚賞。

回答

3

這是一個完全可以接受的方法。

你如何處理異常取決於你。如果例外情況類似於AttemptToReadBeyondLimit,則只需從hasNext返回false即可。如果是類似CommunicationsException那麼通過一切手段拋出RuntimeException

您不應該不必要地添加額外的圖層。

+0

感謝您的反饋oldcurmudgeon。我的確瞭解了使用RunTimeException並不一定是壞事,但我想知道是否有其他設計模式(可能甚至不使用迭代器)封裝了這種行爲,並且還允許我使用服務的檢查異常因爲我希望客戶不必知道異常情況並檢查它們。 – Rahul

0

正如您所提到的,Iterator設計模式API的常見用法需要next方法爲安全。所以,你很少會看到這樣的代碼:

for(... iter. hasNext() ...) { 
    Type t = iter.next(); 
    ... 
} 

所以,我認爲你應該記住這一點,當你設計你Iterator - Service代理。我目前看到的一個誤用是你提到的 - 大約next()拋出異常。

我會嘗試找到一種方法做檢查異常的兩兩件事之一:

  1. 服務API中創建一個「標誌」 - 這意味着你現在有兩個可用的服務,一個叫做「isMoreDataAvailable」,另一個叫做「getData」。

  2. 使內部容器 - 這意味着所述hasNext方法實際上從服務獲取數據,並將其存儲在內部的數據結構爲next方法當被調用時得到。

第一方法的缺點是重新設計服務API的問題 - 不是東西,總是有可能或向後兼容。 第二種方法的缺點是事實上破壞了hasNext方法的「懶惰」特性,因爲現在它不僅僅是檢查而是做很多事情。

+0

感謝MordechayS的建議。不幸的是,我無法重新設計API,因爲我無法編寫它。關於你的第二點,是不是現在將檢查的異常添加到hasNext()中,這也是一個問題? – Rahul

+1

@Rahul你好,歡迎光臨。保持簡單 - 如果'hasNext'方法中的'try-catch'子句關閉,請記錄錯誤並使用'finally'子句返回'false'。請記住,實際的環境問題(如通信問題,在第二個答案中提到...)應該拋出一個運行時異常... – MordechayS

+0

感謝mordechays。然而,我想排序爲「快速失敗」,而不是僅僅返回false,以讓客戶知道服務調用實際上已經失敗,而不是實際上沒有更多的數據,因爲它使得他們有機會在有而不是錯誤地認爲他們遍歷了所有的數據。 – Rahul