Extension Object Pattern

       We need a mechanism that allows us to
  • Add a service interface to a type without exposing it in that type

  • Add behavior to preexisting types such as IFile

    The pattern is called Extension Object and is also known as Extension Interface. Anticipate that an object's interface needs to be extended in the future. Extension Object lets you add interfaces to a class and lets clients query whether an object has a particular extension。

    The Eclipse extension support is class-based. That is, you can add behavior to existing classes, but not add state to its existing instances. The additional behavior is described by an interface.


    getAdapter() returns an object castable to the given class (or null if the interface isn't supported)。

    The IAdaptable interface is used in two different ways in Eclipse:
    1)A class wants to provide additional interfaces without exposing them in the API— In this case, getAdapter() is implemented by the class itself. Adding a new interface requires changing the implementation of getAdapter(). This is useful when a class wants to support additional interfaces without changing its existing interface and thereby breaking the API.

     Here is an implementation of a getAdapter() method in a class that supports the IPropertySource interface:
     Object getAdapter(Class adapter) { 
     if (adapter.equals(IPropertySource.class) 
     return new PropertySourceAdapter(this); 
      return super.getAdapter(adapter);
    }

    public class PropertySourceAdapter implements IPropertySource {
      private Object  source;

      public PropertySourceAdapter(Object source) {
        this.source= source;
      }


      public IPropertyDescriptor[] getPropertyDescriptors() {
        // return the property descriptors.
      }
      //...
    }
    2)A class is augmented from the outside to provide additional services— In this case, no code changes to the existing class are required and the getAdapter() implementation is contributed by a factory. AdapterFactories—Adding Interfaces to Existing Types。

    public class FileWithProperties implements IPropertySource {
      private IFile  file;
      public IPropertyDescriptor[] getPropertyDescriptors() {...}
      public Object getPropertyValue(Object id) {...}
      public boolean isPropertySet(Object id) {...}
      public void resetPropertyValue(Object id) {...}
      public void setPropertyValue(Object id, Object value) {...}
      public IFile toFile() { return file; }
    }

    class FileAdapterFactory implements IAdapterFactory {

      // The purpose of this declarative method is to enable a quick lookup for an adapter.
      public Class[] getAdapterList() {
        return new Class[] {
         IPropertySource.class
        };
      }

      public Object getAdapter(Object o, Class adapter) {
        if (adapter == IPropertySource.class)
          return new FilePropertySource((IFile)o);
        return null;
      }
    }

    Next we have to register the factory for our desired type (IFile) with the AdapterManager. 

    IAdapterManager manager = Platform.getAdapterManager();
    IAdapterFactory factory = new FileAdapterFactory();
    manager.registerAdapters(factory, IFile.class);

    Geting adapter interface by calling:

    Platform.getAdapterManager().getAdapter(this, adapter);


    Here are some points about the extension mechanism:


    1) Multiple adapters for the same type— What happens when the same adapter is registered more than once in a type's hierarchy? The rule is that the most specific adapter wins. Most specific means the first adapter in the base class chain followed by a depth-first order search in the interface hierarchy.


    2) Stateless adapters— Adapters that have no state are the most space-efficient and easiest to manage. You store a single instance of the adapter in a field of the adapter factory or a static variable and return it when it is requested. To reuse a single instance of the adapter for all adapted objects, the adapter methods need to support passing in the adapted object. IWorkbenchAdapter is an interface that enables a stateless implementation. IPropertySource is an interface that does not.


    3) Instance based extensions— IAdaptable supports class extensions. How can you extend instances? IResource supports dynamic-state extension with properties. A property is identified by a qualified name and can be managed either per session or persistently. Refer to the API specification of IResource for more details.


    Which adapters are supported?— You cannot determine the available adapters from just looking at a class interface. You have to read the API documentation to find out which adapters are expected by a service (see for example, org.eclipse.ui.views.properties.PropertySheet). Alternatively, search for references to IAdaptable.getAdapter() to uncover all uses of adapter interfaces.


    4) Adapter negotiation— An IAdaptable client can ask for different interfaces until a suitable one is found. For example, a property sheet can be populated from an IPropertySource adapter. However, a client can also get full control over the Property Sheet view contents by providing an IPropertySheetPage adapter. The Property Sheet view first queries for an IPropertySheetPage adapter and if there isn't one then it uses a default Property Sheet page that queries for the IPropertySource adapter.


    5) Reduced programming comfort— Programming with adapters is more bulky than programming with interfaces directly. With an adapter a direct method call is replaced by multiple statements:

    IPropertySource source=
        (IPropertySource) object.getAdapter(IPropertySource.class);
    if (source != null)
        return source.getPropertyDescriptors();


    Extension Object—implemented as IAdaptable, IAdapterManager, and IAdapterFactory—furthers Eclipse's goal of supporting unanticipated extension by allowing contributors to extend the classes an object can pretend to be. While more complicated than just using objects, the extra complexity is balanced by the additional flexibility.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值