2010-05-29 52 views
7

我很努力的爲大衆消費打包一個API。正因如此,我試圖限制那些只希望公開並支持的方法。當然,在這之下有許多有限的訪問方法。我的內部API類應該全部在一個包中嗎?

問題是,我有很多內部代碼需要訪問這些受限制的方法而不公開這些方法。這就造成了兩個問題:

  • 到 類之間的溝通,因爲這 會使我的這些內部方法 公共我不能創建接口。
  • 我無法訪問受保護或默認的 方法,除非我將大部分 我的內部類放在同一個 包中。

所以,我有大約70或80個內部類在乾淨分離的包,但有過分寬容的訪問修飾符。你會說單一包裝是兩種邪惡中較小的一種,還是有更好的方法能夠掩蓋我的內部方法,同時保留更多的粒狀包裝?

我很想知道這裏的最佳做法。

我已經知道This

+0

我認爲這個問題有點主觀:我個人不喜歡導致內部組織糟糕的設計決策,比如你的全班合一包裝案例。但是做這種事情的正確方式現在還沒有想到。 – incarnate 2010-05-29 07:36:41

回答

7

對於您的問題有兩種解決方案,不涉及將所有類保留在同一個包中。

第一種是使用(Practical API Design,Tulach 2008)中描述的Friend Accessor/Friend Package模式。

第二個是使用OSGi。有一篇文章here解釋OSGi如何完成這一點。

相關問題:12,34

+0

這是一個很好的答案,鏈接到朋友包只是我正在尋找的解決方案。 – Chris 2011-05-28 06:11:27

+0

我很高興能幫到你。我也需要一個解決這個看似嚴重的Java限制。這種模式應該是使用Jetbrains MPS或其他模型驅動的開發工具來擴展J​​ava的理想候選者。 – 2011-05-28 16:09:35

+0

那麼,你仍然必須公開內部抽象Accessor(因此是API的一部分)。 更糟的是,惡意用戶可以提供他/她自己的AccessorImpl,從而迫使您的內部軟件包使用他/她自己的API。這將工作,直到Item類被初始化並觸發IllegalStateException。 – charlie 2012-10-18 13:55:13

2

一個例子可能是Servlet API正如你看到的,他們已經分居了共同的servlet API和HTTP成兩個包。

如果您將代碼分開放在api.jarimplementation.jar之間,那麼您可以使用api.jar用戶不可見的實現接口。 如果類的對象不考慮它們的包,必須以任何方式協作,當然這些方法必須是可見的(至少在實現中)。

+0

+1感謝您的信息。我知道我可以將這個問題封裝起來,但是我真的希望限制那些同時具有api和實現jar的用戶無法以非預期的方式訪問非接口實現方法。 – Chris 2011-05-28 06:14:06

1

是的,你只是不能保護內部實現的東西訪問。有一些技術(如OSGi)可以在運行時/應用程序啓動時提供解決方案。這是一種java語言設計模塊化缺陷(但由於向下兼容性,此後也很難添加)。

我喜歡將公開可見工件添加到/api包和內部到/內部的約定。最後,你最終結束了。

 

# this package is allowed to be accessed by api-users 
com.foo.users.api 
# this is completely internal logic (api implementation) 
# should only be touched by the api-module itself. 
com.foo.users.internal 
 

這樣你就有了乾淨的分隔,並且還可以運行靜態代碼分析代碼規則。

與上面提到的servlet-api一樣,您甚至可以將api和impl進一步拆分爲不同的jar。但是這需要更多的努力來構建生命週期和維護模塊,所以我只會在完整的運行時工件拆分有意義的地方(比如在jsr-spec和impl中)做到這一點。

相關問題