Description: Declaring Implementations and Adapters
Keywords: ref

## 1.1.6 Declaring Implementations and Adapters

There are three kinds of relationships that a protocol can participate in:

- A relationship between a class or type, and a protocol its instances provide or can be adapted to,

- A relationship between an instance, and a protocol it provides or can be adapted to, and

- A relationship between a protocol, and another protocol that it implies or can be adapted to.

Each of these relationships is defined by a source (a type, instance or protocol), a destination (desired) protocol, and an adapter factory used to convert from one to the other. If no adapter is needed, we can say that the adapter factory is the special `NO_ADAPTER_NEEDED` function.

To declare relationships like these, the `protocols` declaration API provides three ``primitive'' declaration functions. Each accepts a destination protocol (that must support the `IOpenProtocol` interface), an adapter factory (or `NO_ADAPTER_NEEDED`), and a source (type, instance, or protocol). These three functions are `declareAdapterForType()`, `declareAdapterForObject()`, and `declareAdapterForProtocol()`, respectively.

You will not ordinarily use these primitives, however, unless you are customizing or extending the framework. It is generally easier to call one of the higher level functions in the declaration API. These higher-level functions may make several calls to the primitive functions on your behalf, or supply useful defaults for certain parameters. They are, however, based entirely on the primitive functions, which is important for customizations and extensions.

The next higher layer of declaration APIs are the explicit declaration functions: `declareImplementation`, `declareAdapter`, and `adviseObject`. These functions are structured to support the most common declaration use cases.

For declaring protocols related to a type or class:

`declareImplementation`( | typ [, instancesProvide=[ ]][, instancesDoNotProvide=[ ]])

  Declare that instances of class or type typ do or do not provide implementations of the specified protocols. instancesProvide and instancesDoNotProvide must be sequences of protocol objects that provide (or are adaptable to) the `IOpenProtocol` interface, such as `protocols.Interface` subclasses, or `Interface` objects from Zope or Twisted.

  This function is shorthand for calling `declareAdapterForType()` with `NO_ADAPTER_NEEDED` and `DOES_NOT_SUPPORT` as adapters from the type to each of the specified protocols. Note, therefore, that the listed protocols must be adaptable to `IOpenProtocol`. See `declareAdapterForType()` in section 1.1.9 for details.

For declaring protocols related to a specific, individual instance:

`adviseObject`( | ob [, provides=[ ]][, doesNotProvide=[ ]])

  Declare that ob provides (or does not provide) the specified protocols. This is shorthand for calling `declareAdapterForObject()` with `NO_ADAPTER_NEEDED` and `DOES_NOT_SUPPORT` as adapters from the object to each of the specified protocols. Note, therefore, that ob may need to support `IOpenProvider`, and the listed protocols must be adaptable to `IOpenProtocol`. See `declareAdapterForObject()` in section 1.1.9 for details. Also, see section 1.1.6, ``Protocol Declarations for Individual Objects'', for more information on using `adviseObject`.

And for declaring all other kinds of protocol relationships:

`declareAdapter`( | factory, provides, [, forTypes=[ ]][, forProtocols=[ ]][, forObjects=[ ]])

  Declare that factory is an `IAdapterFactory` whose return value provides the protocols listed in provides as an adapter for the classes/types listed in forTypes, for objects providing the protocols listed in forProtocols, and for the specific objects listed in forObjects.

  This function is shorthand for calling the primitive declaration functions for each of the protocols listed in provides and each of the sources listed in the respective keyword arguments.

Although these forms are easier to use than raw `declareAdapterForX` calls, they still require explicit reference to the types or objects involved. For the most common use cases, such as declaring protocol relationships to a class, or declaring an adapter class, it is usually easier to use the ``magic'' `protocols.advise()` function, which we will discuss next.