元素工厂用来根据在关闭工作台期间所保存的数据来重新创建工作台模型对象。
在仔细研究元素 factory 扩展之前,我们需要复审在整个平台中用来将特定于插件的行为添加至常见平台模型对象的常规技术。
当浏览各种工作台类时,您将注意到许多工作台接口都扩展了 IAdaptable 接口。
插件使用适配器来将特定行为添加到系统中预先存在的类型中。例如,工作台可能想要资源应答标签和图像以便显示。我们知道,设计时将特定于用户界面的行为添加至低级别对象并不好,那么,可以如何将此行为添加至资源类型呢?
插件可以注册适配器,适配器会将行为添加至预先存在的类型。于是,应用程序代码就可以查询特定适配器的对象了。如果为它注册了一个适配器,则应用程序可以获得该适配器并使用在该适配器中定义的新行为。
通过提供设施来动态地查询适配器以获取对象,我们可以在系统扩展时提高系统的灵活性。可以由新插件来为平台类型注册新的适配器,而不需要更改原始类型的定义。请求特定适配器的对象的模式如下:
//given an object o, we want to do "workbench" things with it. if (!(o instanceof IAdaptable)) { return null; } IWorkbenchAdapter adapter = (IWorkbenchAdapter)o.getAdapter(IWorkbenchAdapter.class); if (adapter == null) return null; // now I can treat o as an IWorkbenchAdapter ...
如果没有为手中的对象注册适配器,则将返回 null 来作为适配器。客户机必须准备处理这种情况。可能会多次出现尚未注册期望的适配器的情况。
工作台使用适配器来从基本平台类型中获得用户界面信息,例如 IResource。适配器屏蔽了基本类型,从而不需要了解特定于用户界面的知识,并允许工作台扩展其接口,而不需要更改基本类型的定义。
如果没有适配器,则可能在工作台 API 中传递的任何类都将需要实现用户界面接口,这将增加类定义的数目,引入紧耦合并在核心和用户界面类之间创建循环依赖性。借助适配器,每个类都实现了 IAdaptable,并使用适配器注册表来允许插件扩展基本类型的行为。
在整个工作台代码中,您将看到通过查询平台核心类型来获取适配器的情况。查询是为了获取对象,以便知道如何应答有关类型且面向用户界面的信息。
当用户关闭工作台时,它必须保存工作台中显示的 IAdaptable 对象的当前状态。对象的状态是通过保存特殊格式的对象 IMemento 的基本数据参数来存储的。还将存储可以根据 IMemento 来重新创建对象的 factory 的标识,并将数据保存在文件系统中。
重新启动平台时,工作台会查找与 IMemento 的 factory 标识相关联的元素 factory。它通过检查 org.eclipse.ui.elementFactories 扩展的添加项的插件注册表来查找工厂。
标记相当简单。我们只需要指定工厂的标识以及实现该工厂的相应的类。
以下代码段来自于工作台 plugin.xml。
<extension point="org.eclipse.ui.elementFactories"> <factory class="org.eclipse.ui.internal.model.ResourceFactory" id="org.eclipse.ui.internal.model.ResourceFactory"> </factory> <factory class="org.eclipse.ui.internal.model.WorkspaceFactory" id="org.eclipse.ui.internal.model.WorkspaceFactory"> </factory> <factory class="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.ui.part.FileEditorInputFactory"> </factory> <factory class="org.eclipse.ui.internal.dialogs.WelcomeEditorInputFactory" id="org.eclipse.ui.internal.dialogs.WelcomeEditorInputFactory"> </factory> <factory class="org.eclipse.ui.internal.WorkingSetFactory" id="org.eclipse.ui.internal.WorkingSetFactory"> </factory> </extension>