- 1. Goals
- 2. Problems
- 3. Discussion
- 4. Structure
- 5. Example
- 6. Control List
- 7. Rules of thumb
Goals
- Converting a class interface to another interface. An adapter allows classes to work together that might otherwise be due to incompatible class interfaces.
- Wrapping an existing class in a new interface
- Compliance of the old component with the new system
Problems
A ready-made component has everything you need to develop your system, but its interfaces are incompatible with the interfaces of your application classes.
Discussion
Reuse has always been painful. One of the reasons was the problem in creating something new while reusing something old. There is always something not quite right or not quite compatible between the old and the new. It could be physical dimensions. It could be sync. These may be unfortunate assumptions or competing standards.
This is similar to the problem of inserting a new three-prong electrical plug into an old two-prong socket - some kind of adapter or intermediary is needed.
An adapter is a creation of an intermediate abstraction that translates or maps an old component into a new system. Clients call methods on the Adapter object that redirect them to calls to the inherited bean. This strategy can be implemented with either inheritance or aggregation.
The adapter functions as a wrapper or modifier on an existing class. It provides a different or translated representation of that class.
Structure
Below, the deprecated display() method for the Rectangle component used in the Rectangle expects to receive "x, y, w, h" parameters. But the client wants to pass "top left x and y" and "bottom right x and y". This inconsistency can be corrected by adding an additional layer of abstraction - i.e. an adapter object.
The adapter can also be thought of as a "wrapper".
Example
The adapter pattern allows other incompatible classes to work together by converting the interface of one class into the interface expected by clients. Female sockets are an example of an adapter. The socket is attached to the ratchet, provided that the size of the actuator is the same. Typical disc sizes in the US are 1/2" and 1/4". Obviously a 1/2" ratchet will not "fit into a 1/4" socket unless an adapter is used. The 1/2" to 1/4" adapter has a 1/2" female connection to mount on a 1/2" shaker and a 1/4" male connection to mount to a 1/4" socket.
Control List
- Define the players: the component(s) you want to use (i.e. client) and the component you want to adapt (i.e. adaptable).
- Determine the interface that the client requires.
- Create a "wrapper" class that can "match the interface" of the client.
- The adapter/wrapper class "has" an instance of the class being adapted.
- The adapter/wrapper class "maps" the client interface to the adapted interface.
- The client uses a new interface
Rules of thumb
- Adapter allows classes to work after they are designed; The bridge makes them work before they are developed.
- The bridge is designed in advance so that the abstraction and implementation change independently. The adapter upgrades so that collaborative classes work together.
- An adapter provides a different interface to its object. The proxy provides the same interface. The decorator provides an extended interface.
- The adapter is designed to change the interface of an existing object. A decorator improves the performance of another object without changing its interface. The decorator is thus more transparent to the application than the adapter. As a consequence, the Decorator supports recursive composition, which is not possible with pure adapters.
- Facade defines a new interface, while Adapter uses the old interface. Remember that an adapter supports two existing interfaces, not defines a completely new one.