2015-12-21 48 views
3

最近,我有談話和我的朋友約的良好做法,以創造公共的API,我們吵了起來,當我們來到返回類型。他告訴我只返回Widen類型,例如列表insted ArrayList。但在我看來,這一切都取決於我們試圖解決的問題。 我看到沒有錯:窄或寬型?什麼在我的公開API返回

ArrayList foo();

當我想說:「嘿,我給你ArrayList的只是確保你長了訪問在O(1)時間元素」

在下面的例子讓我們假設有在方法簽名沒有inforamtion或關於返回什麼樣的圖形或使用什麼表示的文檔

Graph foo();

現在怎麼辦?基於鄰接表或鄰接矩陣,我可能想知道這個圖是有向還是無向的。什麼是最壞的情況可能會導致類似的代碼:

Graph graph = foo(); 
if(graph instanceof DirectedGraph) 
//code 

這是違反了里氏替換原則

你有什麼想法?

回答

2

想想爲什麼你會甚至暴露的API和爲什麼要有人使用它呢? 最明顯的原因將是隱藏您的API用戶的問題(和解決方案)的複雜性。

您的API的用戶並不想關注您首先從他那裏抽象出的實現細節和底層複雜性。

作爲一個API提供者,一般來說,你不想把自己侷限於具體的實現,例如在這個例子中的ArrayList。即使你應該使用ArrayList大部分時間List接口的實現,它不會是不可能讓自己在LinkedList將瓶坯更好的情況。

這會破壞您現有的API,客戶端將不得不重新實施更改。這正是你不想做的。

看看programming to interface概念。

編輯

您是否可以向圖和後面相同的界面圖,將取決於你的使用情況。然而,你可以做的最確切的事情是提供兩個接口,一個用於圖形,另一個用於有向圖,保護你的API用戶免受這些圖形實現的未來變化。

你的API的用戶應該能夠指定他想要什麼類型的圖表,指示與否,你應該能夠隱藏他的具體圖形實現細節。

+0

簡潔的答案。我會補充說_sometimes_ Java泛型在這種情況下很好(但顯然取決於域/上下文)。 –

0

當我想說:「嘿,我給你ArrayList的只是爲了確保 你長了訪問元素O(1)時間」

聽起來像過早優化。

Graph foo();

圖形總是隱式地不受指導。有向圖是直接指向的。除非你已經明確區分了無向圖和有向圖 - 在這種情況下,我將IGraph作爲接口,然後使用Digraph和Graph實現該接口,否則我認爲它濫用了術語來將二元圖形稱爲圖形。

從使用圖形作爲數據類型(無行爲)的角度來看,使用圖表作爲圖形時沒有問題 - 它將簡單地忽略其元素(邊和頂點)的順序。但是,使用圖形作爲有向圖可能會有問題,因爲元素的順序可能是隨機的(如果其元素存儲在bag中)。也就是說,你不能確定元素總是以相同的順序返回,這不會使它們的順序保持不變。

0

當我想說:「嘿,我給你ArrayList的只是確保你長了(1)時間訪問元素O」的

您必須在接口公開必要的東西,不多也不少。因此,如果您需要保證O(1)的訪問,那麼使用ArrayList是正確的,您的實現不太可能因此而改變。

Graph foo();

這個實現告訴你,這兩種圖都可以返回,所以它由你決定,或者根據需要檢查它。

不要做早期優化。

0

我認爲沒有錯的:

ArrayList foo(); 

當我想說:「嘿,我給你ArrayList的只是確保你長了訪問元素O(1)時間」

這不是你在返回ArrayList時唯一說的。你說的是:這個方法返回一個非常具體的List:ArrayList實現,並且這個方法的所有重寫都必須返回這個非常具體的實現,沒有別的。

但是也有一些O(1),因此不ArrayList中列出的其他幾個實現:

  • ()由Arrays.asList返回列表
  • 的CopyOnWriteArrayList
  • 由集合返回的列表。的emptyList()或Collections.singletonList()
  • 任何O(1)列表裹成Collections.synchronizedList()或Collections.unmodifiableList()
  • ...

這會限制你並限制子類(如果該類是爲子類設計的),這樣可能會使代碼難以發展。它並沒有給調用者帶來太多的東西:文檔可以說這個列表是RandomAccess,如果他真的想要一個非隨機訪問列表是RandomAccess,調用者可以創建一個副本。

關於你的第二個例子,如果圖的類型具有相同的Graph接口,調用者不應該關心返回哪個具體實現。

因此,規則可能是:返回您現在和將來可以保證的最精確的接口,以及所有可能的子類。但是,避免在接口類型可以執行時返回具體的實現類型。

當然,這真的取決於您所處理的類型,設計以及用例。設計更多的是藝術而不是科學。

相關問題