The Adapter Design Pattern
The Adapter pattern allows objects with incompatible interfaces to collaborate.
Use the Adapter pattern when you want to allow two incompatible interfaces to work together. This pattern allows a class to work with methods and properties that it does not inherit or implement.
- TypeStructural
- Time ComplexityO(1) Constant Time – The algorithm runs in constant time, irrespective of the input size. Operations like accessing an array element fall into this category.
- Efficiency6
-
Learning Effort
- Average5
- Conceptual5
- Debug and Maintain4
- Implementation3
- Prerequisites4
- Versatility7
Things you should know before you start
- Interfaces Understanding of interfaces in object-oriented programming.
- Composition Understanding of object composition in order to adapt one interface to another.
Minimal Example
Integrating a new payment gateway into an existing e-commerce platform.
interface PaymentProcessor { processPayment(amount: number): void; } class NewPaymentGatewayAdapter implements PaymentProcessor { private newPaymentGateway: NewPaymentGateway; processPayment(amount: number) { this.newPaymentGateway.doPayment(amount); } } const paymentProcessor: PaymentProcessor = new NewPaymentGatewayAdapter(); paymentProcessor.processPayment(100);
What’s happening in thie example
In this example, the NewPaymentGatewayAdapter class adapts the NewPaymentGateway to the PaymentProcessor interface used by the client code. The `clientCode` demonstrates using the adapted interface to process a payment.
How the Adapter Works
The Adapter pattern serves as a bridge between two incompatible interfaces. It allows an object to work with methods and properties that it does not inherit or implement.
This pattern is particularly useful in systems where you can’t modify the source code of existing classes or when you want to create reusable classes that collaborate with classes that don’t have compatible interfaces.
Entities in the Adapter Design Pattern
-
TargetThe Target interface defines the domain-specific interface used by the client code.
- Client has a one-to-many uses relationship with Target
-
AdapterThe Adapter class adapts the Adaptee to the Target interface.
- Adapter has a one-to-one adapts relationship with Adaptee
What to watch out for when using or considering this design pattern.
Avoid using the Adapter pattern when you can modify the existing class to make it compatible. The pattern can overcomplicate the system by adding extra classes.
Design patterns often confused with the Adapter Design Pattern
The following design patterns are often confused with the Adapter
for various resons.
If you’re exploring solutions, have a look through this list and see if
one of these might be a better fit for your problem.
-
Decorator – The Decorator pattern adds new functionalities to objects without altering their structure. This type of design pattern comes under structural pattern as this pattern acts as a wrapper to existing classes.
The Decorator pattern is similar to the Adapter in the following ways.
- Both are structural design patterns.
- Both involve wrapping classes or objects.
- Adapter changes the interface of an existing object, while Decorator enhances an object without changing its interface.
- Adapter makes two existing interfaces work together, whereas Decorator adds new functionality to an object.
-
Bridge – The Bridge pattern decouples an abstraction from its implementation so that the two can vary independently.
The Bridge pattern is similar to the Adapter in the following ways.
- Both are structural design patterns.
- Both involve separating interfaces or implementations.
- Adapter is used to make two existing interfaces work together, while Bridge is used to separate an abstraction from its implementation so they can vary independently.
- Adapter pattern modifies the interface of an existing object, whereas Bridge defines its own interface.