适配器模式的在GOF23中的定义是:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式属于结构型模式,分为类的适配器模式与对象的适配器模式。它们的结构图如下所示:
图1类的适配器模式
图2对象的适配器模式
Eclipse作为一个扩展性很强的平台,那么内部类、接口如何在保持稳定的情况下对外提供更多的服务,在Eclipse的设计上,采用适配器模式是一个很好的选择。 在Eclipse开发中,适配器实现的方式主要有以下两种:
1. 实现IAapter接口。IAapter的接口定义如下:
public interface IAdaptable {
/**
* 根据传入的目标类型返回相应适配对象。
*/
public Object getAdapter(Class adapter);
}
参照“图2对象的适配器模式”,即Adaptee对象还有一个上层接口IAdaper,在这种情况下,欲通 过 Adaptee获得一个目标对象,可以通过调用Adaptee的getAdapter()方法:
public Object getAdapter(Class target) {
if(target == ITarget.class){
Adapter adapter = new Adapter(this);
return adapter;
}
return super.getAdapter(target);
}
通过这种查询获取的方式,客户端就不需要关注如何将对象适配以获得目标对象了。即:
在职责分配上,由被转换的对象来确定如何进行转换,也只有该对象知道如何转换,被转换对象使用了本身的资源来完成转换对象的创建。
2. 为适配对象注册IAdapterFactory, IAdapterFactory的接口定义如下:
public interface IAdapterFactory {
public Object getAdapter(Object adaptableObject, Class adapterType);
/**
* @return 所有可以适配的类型。
*/
public Class[] getAdapterList();
}
这种方式一般使用于对不能修改代码的现有对象进行适配。如eclipse资源管理模型对象IFile、IResource,通过这种适配工厂方式,来完成向目标对象的转换。
客户端的调用方式如下:
IAdapterManager manager = Platform.getAdapterManager();
IAdapterFactory factory = new FileAdapterFactory();
manager.registerAdapters(factory, IFile.class);
3. 一个例子:利用Eclipse属性视图显示自己的属性。
Eclipse的属性视图即Properties View可以用于显示当前所选元素的属性,在很多场合中,属性视图还同时提供属性编辑的功能。属性视图如何根据当前所选对象,获得显示的内容呢,参考PropertySheetViewer的实现,可以发现PropertySheetViewer的显示模型对象为IPropertySource,从所选对象到IPropertySource装换的代码如下:
protected IPropertySource getPropertySource(Object object) {
if (sources.containsKey(object))
return (IPropertySource) sources.get(object);
IPropertySource result = null;
IPropertySourceProvider provider = propertySourceProvider;
if (provider == null && object != null)
provider = (IPropertySourceProvider) Platform.getAdapterManager()
.getAdapter(object, IPropertySourceProvider.class);
if (provider != null) {
result = provider.getPropertySource(object);
} else if (object instanceof IPropertySource) {
result = (IPropertySource) object;
} else if (object instanceof IAdaptable) {
result = (IPropertySource) ((IAdaptable) object)
.getAdapter(IPropertySource.class);
} else {
if (object != null)
result = (IPropertySource) Platform.getAdapterManager()
.getAdapter(object, IPropertySource.class);
}
sources.put(object, result);
return result;
}
可以看出,这就是适配器模式在Eclipse使用的一个场景。 我们在定制自己的属性视图的时候,只要将自己的模型提供IPropertySource 的适配,提供属性视图就可以了。