2010-12-17 39 views
5

有一件事情一直困擾着我在Java是:Java的公開課與私人依賴類

如何創建應該由下游消費者使用,但那麼好聽組織它依賴的類一個單一的公共類包?

例如(有點人爲的),我有一個類UserDao依賴於LdapPersistenceHelper和DBPersistenceHelper。 UserDao類位於名爲com.company.dao的包中,我希望這兩個幫助者位於名爲com.company.dao.persistencehelper的包中。但是,我不想讓這兩個助手足夠通用,以至於可以被其他人使用。我怎麼樣?如果我讓助手「受保護」(確實沒有修飾符),那麼我無法通過UserDao訪問它們。如果我將它們公開,其他人可能會使用它們。

回答

1

一種選擇是將它們放在與公共類相同的包中,但是具有包訪問權。

如果您使用的是OSGi,則可以將實施軟件包保留在導出軟件包集之外。

+0

有趣,我沒有想過用OSGI來解決這個問題 – silk 2010-12-17 23:19:36

3

除非將類放在同一個包中,否則無法執行此操作。無法定義子包可見性。

+0

有個問題。如果我使用帶有沒有修飾符的類的庫,那麼它只能在該包中使用。我在我的項目中創建一個同名的包。我可以以這種方式在我自己的包中使用庫中的類嗎? – 2010-12-17 23:05:59

+0

是的。但該語言旨在防止事故,而不是瀆職。 Stroustrup注意到D&E中C++的相同區別。 – 2010-12-17 23:10:59

+0

是的,你可以。除非它是java.lang,lava.util等:) – Bozho 2010-12-17 23:12:50

6

根本問題是,您正在嘗試使用包來「很好地組織事物」。當創建Java包時,有兩個設計目標:(1)全球唯一的類命名,以及(2)便於使用受保護/默認訪問修飾符。

事實上,您被限制爲具有與包匹配的源文件夾結構不可避免地會導致嘗試使用它們來創建「漂亮/有組織的文件夾結構」。但這不是它創建的目的,因此,它不適用於創建它支持的訪問修飾符。

編輯:順便說一下,我不是以某種方式通過判斷。我意識到我的第一句話可能聽起來很關鍵。很多項目合理地選擇了一個有組織的和可維護的結構,試圖從受保護的訪問中擠出一些額外的感知價值。如果輔助工具是公共的,它真的很糟糕嗎?如果您不相信其他開發人員不會濫用它,他們是否可以信任而不僅僅是更改訪問修飾符?

+0

雖然嚴格Bozho回答這個問題,我更喜歡這個答案,因爲它讚賞設計問題 – silk 2010-12-17 23:18:21

+0

+1這是迄今爲止優越的答案。如果您不準備使輔助類遵守公共接口或成爲可用的通用工具,那麼他們可能在自己的包中沒有地方。事實上,如果它們在UserDao實例的上下文之外沒有意義,它們可能不屬於它們自己的類文件。 – 2010-12-17 23:29:03

+0

@Tim:明顯不真實。您可能擁有整個可重用代碼庫,您通常不希望將其分發給外部使用,因此隱式約定提供將來的二進制兼容性。 – 2010-12-18 00:11:47

1

我不擔心使用它們的人。只需將它們記錄爲內部軟件包,甚至可以將它們置於「內部」或「impl」包中。如果有人反正不恰當地使用它們,他們只能傷害和責備自己(唯一的傷害可能是處理對這些類的向後不兼容的變化)。

如果你想要更強的隔離,使用OSGi。

1

注意:解決這個問題的一個可能方法是(如果您要發佈JAR供其他人使用)是使用混淆器(我建議使用ProGuard)來混淆非公共消費類;這並不妨礙故意的瀆職行爲,但它使人們清楚地知道沒有與這些類別的下游兼容性的合同(並且在技術上很難弄清楚如何使用它們)。