2009-03-03 81 views
2

我要設計這個系統有兩個主要組成部分的交換和輸出邏輯:正在運行的系統

  1. 基地/核心員工。永不改變。
  2. 運行在覈心上的東西。變化相當頻繁。

這將在Java中開發,但問題適用於任何經典的OO語言。如何在運行的系統中替換上面的2而不重新編譯1,並且在運行時不會停止1。可以重新編譯2,但我不應該打擾1.

有沒有設計模式可以做到這一點?我認爲這與插件行爲有些類似,但2對於應用程序的工作實際上非常重要,而不僅僅是一個附加組件。

回答

6

沒有更多的信息,它很難回答...但你可以檢查出OSGi作爲一些想法的起點。

+0

這聽起來像是這種情況下的最佳方法。謝謝! – 2009-03-04 12:12:32

2

我們需要更多的信息來解決這個問題。如果您正在討論在運行時加載全新的邏輯,那可能會非常困難。如果你正在談論的只是交換實現,這可以很容易地與戰略模式完成。

2

你會想爲你經常變化的東西插件模式,再加上一些界面來重新啓動插件。你的核心/基礎(1)將負責動態加載包含你經常變化的東西的程序集/罐子(2)。

1

將源代碼拆分爲兩棵樹很容易。這些編譯後的表單可以分開提供,非核心內容通過核心添加到-classpath進行編譯。

代碼可以在運行時通過類加載器加載(URLClassLoader.newInstance)。你必須小心讓舊代碼被卸載。你需要確保在任何地方絕對沒有(強)引用。

2

這與servlet容器在處理servlet熱插拔時的問題集完全相同。 Web服務器/容器應該連續運行,但必須能夠按需加載新的servlet。

我建議您考慮看看Tomcat的源代碼開始時(available via these subversion URLs。)

2

這基本上就是反射的。正如其他人所說,如果你遵循某種鉤子或插件模式,這應該會讓你獲得最大的成功。基本上它是這樣的:

  1. 在代碼中創建定義良好的接口,描述核心應用程序與插件之間的契約。
  2. 想出一種方法來存儲JAR /類信息在你的配置,這樣就可以通過反射在運行時通過反射加載類型
  3. 加載插件,並呼籲在#描述的接口方法1

現在,如果您開始陷入工作流實施的困境,那麼可能需要調查一下現成的工作流引擎。這裏有太多要提到的,但Google搜索應該讓你開始。

2

我曾經通過在Java之上使用JRuby完成了一些與您的目標類似的事情。核心部分使用Java,並且始終運行,Ruby腳本使用JRuby動態加載。這樣,我可以在不重新啓動(或編譯)Java部分的情況下添加功能。

1

很明顯,這正是爲Eclipse之類的東西而開發的東西;他們使用OSGi構建了一個插件框架。

也就是說,我會選擇可以在JVM上運行的腳本語言,如Jython,Rhino/JavaScript或JRuby。如Spring等框架現在支持the ability to define beans in these languages,並讓它們動態重新編譯。

隨着對動態語言(在JDK6腳本之上)的更多支持到達JVM,這些可能會在將來被廣泛採用。