The general idea is to build an adaptor object that holds
a capability to an object of earlier design called here the base object.
The adaptor serves as a wrapped version of the base object.
The conceptual state of the adaptor is related somehow
to the state of the base object.
The code of the adaptor intercepts the invocation messages and
perhaps the response messages as well.
It is in a position to transform the semantics of the base object.
There are a variety of situations where adaptors arise:
- Application design may evolve and an object design within the application
needs to change and it is easier to build an adaptor than modify
the implementation of the base object.
Obstacles to changing the base implementation include:
- Security: the change would impact the TCB of other applications
that share the type of object or even share instances of the base object.
- Code ownership: the implementation of the base object may be inaccessible
to the application that needs the modified function.
- Long lived objects: base objects may have lifetimes that exceed
the development cycle.
- Wrapping an object can provide a facet
to the base object.
There are two common patterns for creating adaptors:
- Call a creator that returns an adaptor holding no base capability
and let the requestor hand the base capability to the adaptor via a protocol
that may or may not allow for more than one such transaction.
- A source of wrapped objects is a wrapping of the source of base objects.
Ebdow the adaptor creator with a creator (or other source) of base objects.
Each new adaptor comes with its own base object.
In short the creator of the wrapped object is a wrapped creator.
By this scenario the requestor is unable to hold a capability to
the base object.
Often the adaptor need not process the response and tail call optimization
can eliminate an extra copying of the response.
Keykos does this by the adaptor invoking the base object with a return invocation passing its invoker's resume key as the continuation.
Wrappers can be provided externally, even by another agency in another trust domain.
The externally provided wrapper or facet does not increase the TCB of those clients that do not need the facets or wrappers.
For some purposes it is important that the wrapper hold the only capability to the base object.
This is true at least when it is important that a particular slot is the only slot holding a capability to a wrapper.
This is a common requirement in security arguments.
This situation needs a name but I have none now.
Here is the special case of wrapping a legacy application.
Just about any object language provides this wrapper pattern.