2011-04-28 106 views
6

我正在瀏覽Effective Java並閱讀用於創建對象的靜態工廠方法。它的第2章第1項。 3,作者提到像什麼是基於接口的框架?

以這種方式隱藏實現類可能會導致一個非常緊湊的API。這種技術適用於基於接口的框架,其中接口爲靜態工廠方法提供自然返回類型。

我不明白基於接口的框架是什麼?

回答

6

也許改寫這一點會有所幫助:

一個基於接口的框架是一個fr只有在實際交付實現這些接口的類時,才允許用戶/客戶端lib訪問接口。

這種方法的好處在於讓實現者完全控制實現並同時爲客戶端提供穩定的API。

我最近遇到一個例子,客戶端從API方法獲得XmlProcessor。在框架內部,有三種完全不同的處理器實現:一個DomXmlProcessor,SaxXmlProcessor和一個VtdXmlProcessor。單個實現的細節不受客戶關注,可以隨時切換。

+0

對不起編輯錯誤答案:) – Bozho 2011-04-28 10:55:12

+0

@Bozho繼續前進,我的也可以用一些:) – kostja 2011-04-28 11:29:48

+0

太棒了!一個例子值得超過一千個解釋! – dellasavia 2017-01-10 18:42:43

4

基於接口的框架是那些使用接口及其實現設計的框架。

Collection framework是基於接口的框架的一個很好的例子。以這種方式

隱藏實現類可能會導致一個非常緊湊的API

你只需要創建一個接口

interface Animal{ 
public void eat();//hiding the implementation 
public Animal getAnimalInstance();//factory method 
} 

您的實施者將採取落實照顧。

您的API消費者將direcrtly使用的界面,就像我們在收集

List<String> list = new ArrayList<String>(); 

做另請參見

+2

我不認爲你已經解釋了什麼基於接口的框架。你剛剛沒有蛋糕就結了冰。 – 2011-04-28 10:54:38

+0

確定接口允許聲明靜態方法嗎? – darkapple 2011-04-28 11:06:35

+0

我有點困惑。但是這條線索表明我們不能。 http://stackoverflow.com/questions/21817/why-cant-i-declare-static-methods-in-an-interface – darkapple 2011-04-28 11:12:30

1

框架,主要暴露接口,它們的用戶(而非具體實現)

既然你提到布洛赫,我會給與集合框架的例子。你可以看到Collections類有synchronizedX(..)unmodifiableX(..),singletonX(..)方法。這些都是靜態工廠方法,並且有很多這些方法,但它們只返回接口 - ListMap,SetSortedMap。在幕後,有大量的實現你不需要知道。

另一個例子(但沒有關注靜態工廠)是JDBC API。這裏幾乎沒有類 - Connection,Stetement,PreparedStatement,ResultSet等都是接口。這允許許多實現針對不同的數據庫而存在,而用戶沒有任何區別。 (想象一下,如果您必須在您的代碼類中使用,如MySQLStatementOracleConnection等)

1

當您設計軟件時,有核心設計原則來幫助管理複雜任務中涉及的複雜性。

其中一個核心原則是將複雜的問題細分成更小的問題,更易於管理和理解。

接口實際上是一個合同。它定義了一個類必須符合的服務以及如何使用它。該界面隱藏了合同的一個或幾個可能實現的實現細節。

一個典型的Java應用程序將被設計爲具有接口來模擬由軟件的不同部分提供的核心契約。實現細節是隱藏的,因此可以降低複雜性。

更具體一點,可以說你設計一個會計應用程序。所有賬戶都提供相同的基本服務:獲得當前餘額,信貸或提取資金,請求過去操作的摘要。您可以定義一個接口一樣,所有類型的帳戶將符合:

public interface Account { 

    double getBalance(); 

    void credit(double amount); 

    void withdraw(double amount); 

    List<Operation> getOperations(Date startDate, Date endDate); 

} 

根據這個定義,很容易例如提供一個用戶界面,允許用戶來管理它的帳戶。實際上支票賬戶和信用卡賬戶之間存在差異。你將不得不直接在銀行數據庫中管理不同的賬戶,或者遠離其他銀行的賬戶。一個是直接操作,另一個是使用某種網絡協議來執行操作。

但從您的角度來看,您只需要滿足合同。你可以在賬戶上工作。關於如何完成特定帳戶操作的詳細信息不是您的問題。

這是花哨和不錯,但仍然存在問題。你如何獲得你的賬戶?這是來自另一家銀行的折扣賬戶肯定不同於本地賬戶。代碼是不同的。還有創建它的方法。對於遠程帳戶,您需要例如其他銀行服務器的網絡地址......另一個可能需要數據庫ID。

每次您需要擁有一個帳戶時,您都可以明確地重新創建它,或者使用所有實現細節獲取它。獲得一個遙遠的帳戶或本地帳戶是非常不同的。

在應用程序的一部分中分離這種複雜性是一種很好的做法。它符合將複雜任務細分爲更小,更簡單的任務。

我給出了會計應用的例子,但實際上我們可以更一般。在任何軟件中創建對象和檢索已經創建的對象是一個非常普遍的問題。所以我們有一個可以保持清潔的方式來做這件事的共同「好方法」。

管理創建獲取特定對象的複雜性的代碼隱藏了實際上對象是如何構造或給定的,稱爲工廠。

如果Java程序員使用工具來管理軟件複雜性,那麼將工廠(隱藏創建/查找對象的複雜性)和接口(隱藏每個對象實現的複雜性)相結合。