Adapter
05 Mar 2022Intent
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't othersie because of incompatible interfaces.
Also known as
Wrapper
Applicability
Use the Adapter pattern when:
- You want to use an existing class, and it's interface does not match the one you need.
- You want to create a reusable class that cooperates with unrelated or unforseen classes, i.e. classes that don't necessarily have compatible interfaces.
- (Object adapter only)You need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of it's parent class.
Structure
Participants
- Target: defines the domain-specific interface that Client uses.
- Client: collaborates with objects conforming to the Target interface.
- Adaptee: defines an existing interface that needs adapting.
- Adapter: adapts the interface of Adaptee to the Target interface.
Collaborations
Clients call operations on an Adapter instance. In turn, the adapter calls Adaptee operations that carry out the request.
Consequences
Class and object adapters have different trade-offs. A class adapter:
- adapts Adaptee to Target by committing to a concrete Adaptee class. As a consequence, a class adapter won't work when we want to adapt a class and all it's subclasses.
- lets Adapter override some of the Adaptee's behavior, since Adapter is a subclass of Adaptee.
- introduces only obe object, and no additional pointer indirection is needed to get to the adaptee.
An object adapter:
- lets a single Adapter work with many Adaptees, i.e. the Adaptee itself and all of it's subclasses. The Adapter can also add functinality to all Adaptees at once.
- makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making Adapter refer to the subclass rather than the Adaptee itself.
Sample Code
Related Patterns
- Bridge has a structure similar to an object adapter, but Bridge has a different intent: It is meant to separate an interface from it's implementation so they can be varied easily and independently. An adapter is meant to change the interface of an existing object.
- Decorator enhances another object without changing it's interface. A decorator is thus more transparent to the application than an adapter is. As a consequence, Decorator supports recursive composition, which isn't possible with pure adapters.
- Proxy defines a representative or surrogate for another object and does not change it's interface.