我對OSGi世界有點新鮮。有些概念仍然沒有我。OSGi UI應用程序的最佳實踐
我正在嘗試使用Swing,Equinox和Declarative Services創建圖形OSGi應用程序。目標是簡化爲應用程序創建插件和擴展。
我偶然發現了一個設計問題,因爲我從頭開始做這件事,所以我想使用我所能做的所有最佳實踐。
我確實有一個包含API的包,並且只公開要作爲服務實現的接口。
public class SomeClass {
}
public interface Manager<T> {
void add(T obj);
void update(T obj);
void remove(T obj);
}
public interface SomeClassManager extends Manager<SomeClass> {
}
public interface Listener<T> {
void added(T obj);
void updated(T obj);
void removed(T obj);
}
public interface SomeClassListener extends Listener<SomeClass> {
}
比方說,我有一個包(核心),提供一種服務,是特定類型的對象(它基本上包含一個內部列表和添加,刪除和更新它)的經理。
public class SomeClassCoreManager implements SomeClassManager {
private ArrayList<SomeClass> list = new ArrayList<SomeClass>();
private ArrayList<SomeListener> listeners = new ArrayList<SomeListener>();
protected void bindListener(SomeListener listener) {
listeners.add(listener);
}
protected void undindListener(SomeListener listener) {
listeners.remove(listener);
}
public void add(SomeClass obj) {
// Adds the object to the list
// Fires all the listeners with "added(obj)"
}
public void update(SomeClass obj) {
// Updates the object in the list.
// Fires all the listeners with "updated(obj)"
}
public void remove(SomeClass obj) {
// Removes the object from the list.
// Fires all the listeners with "removed(obj)"
}
}
我也有需要主UI的護理的第二束(UI)。它不應該「關心」管理自身的對象,而應該在添加,刪除或更改對象以便更新JTree時收到通知。爲此,我使用了一個白板模式:UI捆綁包實現了一個服務,Core包使用該服務來觸發對象更改事件。
public class MainWindow extends JFrame {
private JTree tree = new JTree();
private SomeClassManager manager;
protected void activate() {
// Adds the tree and sets its model and creates the rest of the UI.
}
protected void bindManager(SomeClassManager manager) {
this.manager = manager;
}
protected unbindManager(SomeClassManager manager) {
this.manager = null;
}
}
public class SomeClassUIListener implements SomeClassListener {
public void added(SomeClass obj) {
// Should add the object to the JTree.
}
public void updated(SomeClass obj) {
// Should update the existing object in the JTree.
}
public void removed(SomeClass obj) {
// Should remove the existing object from the JTree.
}
}
我在這裏的問題是:
的主窗口中的DS組件。我正在使用其激活器來啓動整個用戶界面。實例創建由OSGi處理。
爲了從管理器獲取更新,我將SomeClassUIListener作爲聲明服務公開。它的實例也由OSGi處理。
我應該如何從SomeClassUIListener訪問JTree模型的實例?
我已經提出了幾種選擇,但我不知道該使用哪個:
選項1: 使用某種類型的用戶界面包(如吉斯或微微)內部DI系統,並把它在一個靜態方法的類中獲取並在整個bundle中使用它。
這種方法似乎被一些人所淹沒。
選項2: 注入到主窗口的引用(通過將其變成服務)在通過的OSGi的SomeClassUIListener和從那裏。這是可能的還是可取的?在我看來,這是更簡單的解決方案。但是,另一方面,隨着用戶界面變得越來越複雜,這不會讓組件配置文件變得混亂嗎?
選項3: 爲聽衆創建單獨的包並使用OSGi更新MainWindow。這在我看來有點極端,因爲隨着UI複雜性的增長,我將不得不創建大量的bundle。
選項4: 使用MainWindow類實現偵聽器。但是,主UI界面中的服務越多,MainWindow類就越大。我認爲這不是一個好的選擇。
我想不出更多的選擇。上述任何一條路要走嗎?還是有另一種選擇?
預先感謝您。
編輯:
只是爲了澄清爲彼得柯瑞恩斯了這個問題有些疑惑。
我的目標是將用戶界面從Manager中分離出來。由經理我的意思是一種存儲庫,其中存儲某種類型的對象(例如,如果您考慮Oracle的JTree教程http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html,管理器將包含Books的實例)。
經理可能會被任何其他套件使用,但根據我目前的計劃,它會通知任何在其中註冊的收聽者。監聽器可能是主要的用戶界面包,但也可能是任何其他選擇監聽更新的包。
Richard Hall的OSGi in Action書中有一個基於此模型的GUI程序。你也可能想看看http://felix.apache.org/site/apache-felix-application-demonstration.html –
我檢查過你提到的例子。本書的源代碼的確有些東西可以回答我的問題!在第11章的paint-example-ds中,windowlistener暗示了一個解決方案:我可以在將SomeClassCoreManager綁定到MainWindow時註冊監聽器。這樣我就可以在監聽器中注入我需要的任何組件。我提到的來源可以在[link](https://code.google.com/p/osgi-in-action/) –