Flylib.com

Books Software

 
 
 

Object Model

[Previous] [Next]

Object Model

The Adapter design pattern is a fairly straightforward concept to grasp. However, as you can see by reading through the scenarios, you can choose from alternative designs depending on whether your intention is to adapt a class, an object, or a function, and on whether you want the adapter to be transparent or opaque . (The benefits and drawbacks of these types of adapters will be explored further in the "Ramifications" section of this chapter.) With so many types of adapters, I think it's only fair to illustrate object models for a variety of possibilities. Figure 4-3 below, and Figures 4-4 and 4-5 on the following page, model class, object, and function adapters, respectively. Figures 4-3 and 4-4 are transparent adapters, while Figure 4-5 is an opaque adapter.

click to view at full size.

Figure 4-3. Transparent Class Adapter.

click to view at full size.

Figure 4-4. Transparent Object Adapter (with events).

click to view at full size.

Figure 4-5. Opaque Function Adapter.

[Previous] [Next]

Roles

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 follows :

  • Client Collaborates with all objects that implement the expected interface.
  • ExpectedInterface (Map) Defines the interface expected by the client.
  • Adapter (SMap) Serves as a bridge between a client that requires a specific interface (ExpectedInterface), and other classes, objects, and functions that contain the functionality desired but would otherwise be impossible to leverage because the interfaces they expose are incompatible with the interface the client expects.
  • Adaptee (Collection) Contains functionality that is useful to the calling client. An adaptee might be in the form of a class, object, or function. However, because the interface exposed by the adaptee is incompatible with the interface expected by the client, interaction is possible only indirectly through the adapter.
[Previous] [Next]

Relationships

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, clients might have access to the adaptee if the adapter is transparent.

[Previous] [Next]

Ramifications

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 otherwise unattainable when the interface expected by the client is incompatible with the interface exposed by the source of the functionality.

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.

Advantages of Visual Basic-Enforced Transparency of Class Adapters

A single adapter instance can serve the needs of clients that require the new interface and clients that use the interface exposed by the source.

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 sensible alternative to a new interface.

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 implementations . The adapter could delegate one-for-one all invocations made through the adaptee interface directly to the object via its reference. Then again, because the adapter has inherited the interface of the adaptee, it could just as easily define new behavior for any function in the adaptee interface. If the reference to an object that supports the adaptee interface is publicly settable from the adapter, all implementations mentioned here are possible. In addition, the adapter could dynamically realize new behavior for the adaptee interface at run time by obtaining references to objects that are instances of unique classes that implement the adaptee interface.

Disadvantages of Visual Basic-Enforced Transparency of Class Adapters

{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}

You cannot privately inherit the implementation of the adaptee class, so the adaptee is exposed whether you like it or not. If your intention is to create an opaque adapter, you cannot implement a class adapter, and you must implement an Opaque Object Adapter design pattern.

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 stating , "Bad interface for Implements." Microsoft Excel 97 was totally revamped to support Microsoft Visual Basic for Applications 5 technology, which implied you could do everything in Excel 97 that you could do in Visual Basic 5. Unfortunately, that isn't true. For example, you can create classes in Excel 97, but you cannot inherit interfaces from other classes. (This functionality was changed in Excel 2000.) In short, you need transparent object adapters for those times when inheritance is not possible.

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.