The Adapter design pattern is a
Figure 4-3. Transparent Class Adapter.
Figure 4-4. Transparent Object Adapter (with events).
Figure 4-5. Opaque Function Adapter.
The roles and functions of the elements of the Adapter design pattern, as well as how they relate to the elements in the scenarios discussed previously, are as
As reflected in the three object models, the adapter class implements the interface (ExpectedInterface) expected by the client. Upon client invocation, the adapter class delegates the work to the adaptee. Furthermore,
Existing functionality that has been proven to be reliable can be plugged in to new system architectures without compromise to that functionality. The Adapter design pattern defines a class that supports the interface expected by a client in a given domain. This class exhibits a loose coupling of interface and implementation and encapsulates the delegation of work to classes, objects, and functions that contain the desired functionality. This implementation of the functionality by the client would be
Class adapters are always transparent in Visual Basic because Visual Basic supports only public interface inheritance. This constraint has advantages and disadvantages, which are mentioned in the following sections.
A single adapter instance can serve the needs of clients that require the new interface and
Instead of disrupting the implementation of a class by modifying its interface or having it inherit new ones, you can extend its functionality by defining an adapter that inherits a new interface as well as the class's existing interface. Therefore, the client will deliberately maintain a reference to both interfaces from the same adapter instance. In reality, you cannot fully anticipate how an existing class will be extended to support the intentions of a client. Modifying an interface is a "no-no." An interface serves as a contract between a client and the object serving up that interface. Breaking the contract usually breaks the collaboration between the client and its server objects, which ultimately leads to system failure. Applying multiple inheritance to a designated class can be a good idea in many situations; however, you should reconsider excessive inheritance that is motivated by the constant iterative process of identifying new functionality. Also, you should take into account the scope of the utility value for supporting a new interface. An Adapter design pattern is a
If you refer back to the Transparent Class Adapter object model (see Figure 4-3), you will notice that the Adapter class inherits the interface of the adaptee (not its implementation), and that it also contains a reference to an object instance that supports the adaptee interface. The Adapter design pattern suggests a few advantageous implementation possibilities. If the reference to an object that supports the adaptee interface is private to the adapter, the adapter could define two possible
You cannot privately inherit the implementation of the adaptee class, so the adaptee is exposed whether you like it or not. If your
Opaque adapters maintain private object references to adaptee instances, or private access to non-object-oriented adaptee functions. With this feature comes the full benefit of encapsulation. Because only the adapter is aware of the adaptee's existence, individual concrete adapter classes that implement the same abstract interface expected by the client each could adapt different objects or functions that would produce the preferred results.
Transparent object adapters have the same goals and provide the same benefits as transparent class adapters. However, sometimes it is not possible to inherit the interface of an adaptee. In Visual Basic, if you try to inherit the Collection interface you will get a compile-time error
Class adapters by default allow you to override the behavior of the adaptee. Object adapters cannot override the behavior of adaptee objects unless the adaptee makes the opportunity available. This opportunity comes in the form of events that must be defined in the adaptee class. These events can then be raised at will by the adaptee objects. Figure 4-4 illustrates a Transparent Object Adapter in which the adaptee object raises events and the adapter handles those events. The designer of a class must have the foresight to determine whether instances of the class should raise events to allow interested parties the opportunity to produce varying behaviors upon event notification.