2012-10-09 24 views
3

我最近設計了一個API來包裝數據存儲實現,並允許其他開發人員使用此API爲其數據建立索引並根據關鍵字查詢數據庫。我在查詢方法中使用了Response/Reply模式,因爲Jaroslav Tulach提到當需要添加參數時,它可以避免保持更改API接口(實際API設計的第97頁)。其他開發人員認爲使用方法重載是更好的方法。你能分享你在設計中使用兩種不同方法的經驗嗎?以下是我和其他開發者之間的對話。響應/回覆模式與API設計中的方法重載

Me: 響應/回覆模式看起來很乾淨,因爲越來越多的參數可以通過API進化添加到API接口中。在接口中有超過10多種重載方法可能會讓其他開發人員感到困惑。他們如何弄清楚使用哪種方法?

其他開發者的論點: 隨着API的發展,你不應該繼續添加參數。如果您不斷在API接口中添加參數,則您的API設計存在問題。結果,重載方法的數量很少,所以它不會打擾開發人員。更重要的是,Java框架中常常會出現大量的重載方法實現。

Me: 很容易管理以前版本API的後兼容性。您不必更改界面。更改界面將打破其他開發人員現有的代碼。

其他開發者的說法: 如果我改變實現,添加參數,其他開發人員應當根據新的API更新他們的代碼。如果新的參數是可選的,爲什麼要添加它。

+0

不確定是否每個人都明白「回覆/回覆模式」的含義。我不。你能提供一些參考嗎? – Sameer

+0

@Sameer:他做過:'實際API設計中的第97頁' – jgauffin

+0

響應/答覆模式。 http://en.wikipedia.org/wiki/Request-response –

回答

0

沒有本質區別,既不能降低固有的複雜性。當然,我們總能找到任何選擇的支持用例;在不知道你的具體問題領域的情況下,其他人不能僅僅根據一些抽象原則選擇一個最喜歡的。

我會建議,儘管選擇一個現在很簡單的解決方案。不要擔心「未來的變化」

1

我相信我們是在比較

invoke(int param1, string param2) { ... } 

    invoke (string param3, int param4, int param5) { ... } 

等所有有效的參數組合

invoke(requestClass theRequest) 

它這樣使用

request.set("param1", value); 
    request.set("param2", value); 
    invoke(request); 

這裏有幾個交易點。

請求方法的缺點是主叫方可以提供的參數組合無效,並不會收到編譯時警告 - 錯誤不被發現,直到運行時。

但日益增長的接口可能會完全失控,你可以在你需要的方法數組合爆炸。

您可以查看SQL作爲一個非常豐富的請求的示例 - 在我看來很清楚,有些情況下結構良好的查詢語言或請求對象優於逐個參數的方法重載方法。

我個人的經驗法則是:如果您正在尋找10種不同的重載方法,則應考慮請求對象。

2

其他開發人員的觀點:隨着API的發展,您不應該繼續添加參數。如果您不斷在API接口中添加參數,則您的API設計存在問題。

這是一個相當天真的觀點。所有的API都在發展。這不是我們想要的東西,但告訴我一個客戶/客戶,第一次就能正確完成規範......

參數的請求/回覆類型非常好,因爲它很容易獲得向後的可比性。一旦創建了第二個版本的API,我們就不必修改現有的代碼。

考慮一下:

public class GetUserRequest 
{ 
    string Id; 
} 

public class GetUserReply 
{ 
    string Id; 
    string DisplayName; 
} 

和API接口:

public class MyCoolApi 
{ 
    GetUserReply GetUser(GetUserRequest request); 
} 

(API的結構取決於實現的類型)

現在,我們得到了新的要求:所有用戶都應該包含年齡。

我們只要按照開/關的原則,繼承回覆類:而第2個的用戶反序列化的版本2

public class GetUserReply2 : GetUserReply 
{ 
    string Id; 
    string DisplayName; 
    int Age; 
} 

所有版本1個的用戶將反序列化的版本1。

傳入參數也一樣。您可以使服務(API)類成爲只根據Request類版本在後臺調用正確api實現的代理(代理模式)。

結論:Request/Reply爲我們提供了更多的靈活性contra方法重載。