Jos*_*elo 5 java swing osgi declarative-services equinox
我对OSGi世界有些新意.还有一些概念让我望而却步.
我正在尝试使用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> {
}
Run Code Online (Sandbox Code Playgroud)
假设我有一个bundle(Core),它提供的服务是某些类型对象的管理器(它基本上包含一个内部List并添加,删除和更新它).
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)"
}
}
Run Code Online (Sandbox Code Playgroud)
我还有第二个包(UI)来处理主UI.它不应该"关心"管理自身的对象,但是在添加,删除或更改对象以更新JTree时应该通知它.为此,我使用了一个Whiteboard模式:UI包实现了一个服务,Core bundle使用该服务来触发对象更改事件.
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.
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题如下:
MainWindow是一个DS组件.我正在使用它的激活器来启动整个UI.实例创建由OSGi处理.
为了从管理器获取更新,我将SomeClassUIListener公开为声明式服务.它的实例也由OSGi处理.
我应该如何从SomeClassUIListener访问JTree模型的实例?
我提出了几个选项,但我不确定使用哪个:
选项1: 为UI包(如Guice或Pico)使用某种内部DI系统,并将其放在具有静态方法的类中以获取它并在整个包中使用它.
一些人似乎不赞成这种做法.
选项2: 通过OSGi在SomeClassUIListener中注入对MainWindow的引用(通过将其转换为服务)并从那里开始.这是可行的还是可取的?在我看来,这是更简单的解决方案.但是,另一方面,随着UI变得越来越复杂,这不会使组件配置文件变得混乱吗?
选项3: 仅为侦听器创建单独的包,并使用OSGi更新MainWindow.这在我看来有点极端,因为随着UI复杂性的增长,我将不得不创建大量的bundle.
选项4: 使用MainWindow类实现监听器.但是,主UI包中的服务越多,MainWindow类就越大.我认为这不是一个好选择.
我想不出更多选择.以上任何一种方式都可以吗?还是有其他选择吗?
先感谢您.
编辑:
只是为了澄清Peter Kriens对这个问题有些怀疑.
我的目标是将用户界面与Manager分离.通过管理器我的意思是一种存储库,我在其中存储某种类型的对象(例如,如果您在http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html上考虑Oracle的JTree教程,经理将包含图书的实例).
管理员可以被任何其他捆绑使用,但根据我目前的计划,它会通知在其中注册的任何听众.侦听器可以是主UI包,但也可以是选择侦听更新的任何其他包.
这里的一些选择是将树模型实例作为侦听器方法中的参数传递。
public void added(JTree tree, SomeClass obj)
Run Code Online (Sandbox Code Playgroud)
这样监听器管理器将只负责监听器逻辑,而不负责树状态。
另一个不错的选择是创建一个单独的TreeProviderService,负责JTree为应用程序保存和提供单例实例。在这种情况下,您将TreeProviderService直接从听众那里消费。