IAdaptable是Eclipse插件开发中非常重要的一个接口,在整个插件体系中也起着举足轻重的作用。网上也有不少文章来介绍这个接口的用法,因为我没有碰到那些文章中提到的一些IAdaptable应用场景,所以开始的时候对这个接口不以为然:不就是一个适配器吗?有那么重要吗?随着项目的进展,IAdaptable终于让我体会了它的好处。
先来介绍一下我的项目情况:我的项目是一个开发工具插件,其核心就是各种xml配置文件的编辑器。编辑器的组件体系比较复杂,就像芭比娃娃,一成套一层的,比如多页编辑器中套单页编辑器,单页编辑器中根据不同的内容又分成不同的区块,区块还包含最终的编辑元素,比如text, combobox等等。而要编辑的内容模型内容以及相关的资源信息(比如IProject, IFile, IPath)大部分都位于组件结构的最外层,比如IEditorPart, IEditInput中。
而不同的组件层次可能需要不同的信息,为了降低耦合度,我开始定义和使用各种需要的资源内容的提供接口,比如IProjectProvider, IModelProiver, IConfigProvider,ISelectionProvider等等,这样最外层实现了一堆Provider,然后根据不同的需要往内层传,从外层到最终需要该资源的层之间不断的传递,而中间起传递作用的各个层次都来实现这些IXxxxProvider接口。开始一两个还无所谓,后来需要传递的资源多了,层次多了,维护非常麻烦(如果增加一种需要的资源,就定义一个IXxxxProvider)。于是开始寻找更好的方法来处理这种维护上的麻烦,一次偶然的机会在EMF generate的代码中发现了IAdaptable接口的用法:
- public Object getAdapter(Class key) {
- if (key.equals(IContentOutlinePage.class)) {
- return showOutlineView() ? getContentOutlinePage() : null;
- }
- else if (key.equals(IPropertySheetPage.class)) {
- return getPropertySheetPage();
- }
- else if (key.equals(IGotoMarker.class)) {
- return this;
- }
- else {
- return super.getAdapter(key);
- }
- }
能不能将所有Provider合成一个呢?对,这样中间的各个层次之间只需要实现IAdaptable接口就可以了,如果发生变化,只需要修改两头:即资源提供者和资源消费者,于是我的最外层定义了一个长长的IAdaptable的实现方法getAdaptable():
- public Object getAdapter(Class key) {
- if (key.equals(IContentOutlinePage.class)) {
- return showOutlineView() ? getContentOutlinePage() : null;
- }
- if (key.equals(IPropertySheetPage.class)) {
- return getPropertySheetPage();
- }
- if (key.equals(IGotoMarker.class)
- || key == IEditingDomainProvider.class
- || key == ISelectionProvider.class
- || key == IClipboardProvider.class
- || key == IAdapterFactoryProvider.class) {
- return this;
- }
- if (IProject.class.equals(key)) {
- return getProject();
- }
- if (BaseConfig.class.equals(key)) {
- return ((IConfigProvider) this).getConfig();
- }
- if (EObject.class.equals(key)) {
- return getModel();
- }
- if (DoradoXMLResourceImpl.class.equals(key)) {
- return ((IResourceProvider) this).getResource();
- }
- if (key == EditingDomain.class) {
- return editingDomain;
- }
- if (key == AdapterFactory.class) {
- return adapterFactory;
- }
- if (key == BaseActionBarContributor.class) {
- return getActionBarContributor();
- }
- if (key == Clipboard.class) {
- return getGlobalClipboard();
- }
- return super.getAdapter(key);
- }
如果这个数据模型是独一无二的,就直接根据模型类型返回模型,如果一个Provider可能会提供多个模型或者一种模型类型对应多个Provider那么就返回Provider,让模型消费者决定来获取哪个模型。
虽然重构为使用IAdaptable花了不少时间,但是对于后期的变动却少了不少的麻烦,而且代码也减肥了不少。
安徽新华电脑学校专业职业规划师为你提供更多帮助【在线咨询】