A type represents an aggregation of interfaces. Like interfaces, types are also defined by the host and implemented by the plug-in. A type is an entirely abstract entity that groups related interfaces together, providing a conceptual umbrella for the different APIs represented by the type's constituent interfaces. Types allow for a high-level representation of a feature to be implemented or problem to be solved. Interfaces express the way you intend to factor the problem represented by the type. You can think of interfaces as the implementation of a type.
For example, say you're developing an application called ImageViewer and you want to allow third parties to add file format support for different types of images using plug-ins. You might define the type
ImageAdaptorType
, which would consist of two interfaces,
ImageIOInterface
and
ImageSnifferInterface
.
ImageIOInterface
might consist of two functions. The first function would take a parameter of type
CFURLRef
and return a special
ImageViewerImage
type defined by ImageViewer to represent an image. The second function would take parameters of type
CFURLRef
and
ImageViewerImage
and write the image to the location described by the URL.
ImageSnifferInterface
might define a function that would take a
CFURLRef
parameter and return a
Boolean
value indicating whether the file pointed to could be read.
Because an interface cannot ever change once it has been published, types must support multiple interfaces. Instead of changing a type's interface, you simply add a new interface to the type with the changed or additional functionality. In this way, a single plug-in might support different versions of a host application by implementing a different interface for each version. The type would remain the same; it would be up to the host application to locate and use the appropriate interface.
It is also possible to define optional interfaces for a type. For example, a host application might define a type with an optional interface specific to a piece of add-on hardware. The host application could test for the presence of that hardware at runtime and, if it exists, the host could request the hardware-specific plug-in interface. If a plug-in implementor doesn't want to support the hardware specific functionality, they need not implement that interface.