2011-10-28 168 views
3

這個問題有點受到我詢問的previous question的啓發。在Java中處理插件是否有很好的模式?

我寫的大部分代碼都與API有關,API本質上必須易於擴展。一個常見的問題是,我和我的團隊的其他成員正在如何處理插件,即可能擴展我們自己的接口並在最終實現中的類應該感覺像是解決方案的原子部分。我想特別是在以下類型的用例(使用汽車來比喻)

接口:

Car 

提供的實現:

Ford 
Audi 

第三方實現方式:

Toyota 

我們通常需要的是,類CarDealer需要知道Car的所有現有實現,而不必強制第三方在配置文件中明確聲明Car。我一直在想的一個想法是讓Car的實現註冊自己CarDealer,但是這會打開一個新的蠕蟲罐,因爲Toyota(或任何其他實現)不會被初始化,直到它們被明確引用,這是一個catch22。註釋Car的實現然後遍歷代碼並使用相關注釋初始化任何類也是一種方法,但恐怕這可能會非常耗費資源。

我覺得我們不能成爲這個問題的第一個,所以有沒有已知的設計模式來解決它呢?

+0

請參閱http://stackoverflow.com/questions/7587318 – Mot

回答

0

您可以爲第三方類指定位置,然後使用反射來實例化它們。

或者編寫自定義的類裝載器

+0

使用固定的位置是我們最終的目標,但它比我想要的要笨拙。 你能詳細說明一下自定義類加載器是如何工作的嗎? – mikek

3

看看java.util.ServiceLoader。本質上你創建了一個接口,然後服務的所有實現者都可以包含一個文件/ META-INF/services/<完全限定名稱的接口,列出他們jar中的所有實現。

ServiceLoader可以用來加載在類路徑中發現的所有實現(例如,JDBC 4.0要求驅動程序也使用它來擺脫使用Class.forName(...)來加載驅動程序)。

0

有2件事說起這個情況時進入我的腦海:

  1. 聲明的方法在你所謂的getName(抽象實現(或接口)),在這種情況下,豐田將返回「豐田「 等等。然後,您可以考慮掃描整個類路徑並收集Car的子類(use this method for that)。最後使用(靜態?)工廠方法來獲取所有「Car實現」或按名稱選擇它們。使用反射來獲得新的對象。

  2. 有一個名爲OSGi的平臺,它是專門爲處理插件而創建的(通過使用OSGi服務)。當使用Spring DM與OSGi進行通信時,它變得非常容易使用。有兩個主要實現:Felix和Equinox。

總結:如果您可以選擇平臺 - 選擇OSGi。如果你不能 - 我想你將不得不掃描類路徑。

相關問題