1.标准的适配器模式
适配器模式:把一个类的接口变换为客户端所期望的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
为了便于下面的讨论,我们延用设计模式书籍中使用的三个角色:
Adaptee(源,待适配):需要适配的类型,行为需要被复用
Target(目标):适配的方向,也就是我们期待的接口,客户端定义的契约
Adapter(适配器):承担类型匹配任务的具体类,Target类型实现类
Adapter是需要实例化使用的,所以是具体类,而Target代表目标类型的抽象
类适配器模式:适配器Adapter同时继承了目标类型Target和源Adaptee
缺点:如果源Adaptee有一系列类型(有共同的顶级父类型),那我们需要对这一系列类型中的每个类型(源及其子类型)都产生一个适配器类实现,也就是说,会引入大量的类型,带来类型膨胀的问题。
对象适配器模式:适配器Adapter继承了目标类型Target,组合了源Adaptee
缺点:无法定制Adaptee的行为
声明一个适配器接口,所以实现此接口的类都具备适配能力:
publicinterface IAdaptable { public Object getAdapter(Class adapter); }
获取适配类型:
if (source instanceof IAdaptable) { IAdaptable adaptable = ((IAdaptable)source); Object instance = adaptable.getAdapter(Interface2.class); if (instance != null) ((Interface2) instance).operation(); }
这样子仅仅能够使用别人提供好的适配类型,而无法做到自己扩展适配类型
AdapterManager.getAdapter(this, adapter)
如果存在这样一个适配管理者,把所以的适配类型都管理起来,我们就可以很容易的自己扩展类型了
2.eclipse中的类型扩展机制
Eclipse平台本身是一个微内核(micro kernel)加核心插件(core plug-ins)的结构,微内核是指Ecllipse的OSGI实现Equinox(当然包含了扩展点机制的支持),这里的核心插件就是指:runtime、resource、workbench。而这里的平台运行时为我们提供的主要的特性是:类型扩展支持(IAdaptable、IAdapterFactory、IAdapterManager)和线程支持(Job、ISchedulingRule)。我们今天要讨论的就是类型扩展支持。
org.eclipse.core.runtime.IAdaptable:用来声明特定类型是否是可以被适配的并提供了默认适配器类org.eclipse.core.runtime.PlatformObject在Eclipse中,只要是继承自以上接口或者抽象类的类型,就被视为“可扩展类型”。
org.eclipse.core.runtime.IAdapterFactory:用可以将自定义的适配逻辑放入IadapterFactory中
org.eclipse.core.runtime.IAdapterManager:可以将自定义的适配逻辑实例注册到IadapterManager中。注册的方式有两种,通过代码静态注册:IAdapterFactory.registerAdapters(IAdapterFactory factory, Class adaptable)和通过实现org.eclipse.core.runtime.adapters扩展点注册。
IadapterManager提供了两种getAdapter和loadAdapter两种接口,如果是使用扩展的方式添加的类型,getAdapter的方式不会去强制启动你的插件,而loadAdapter的方式会去强制启动你的插件。如果是以代码的方式注册的,那也直接取决于所在插件是否启动。
尽管eclipse的类型扩展机制比较灵活,但是凡事都有其缺陷。eclipse在提供灵活的机制的同时,并没有考虑到类型冲突问题,所以在我们使用的时候同时也应该注意管理好类型。
参考:http://www.blogjava.net/zhuxing/archive/2009/10/13/222860.html