Intent
It's a structural design pattern, which converts the interface of a class into another interface clients expect. The adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
This is done simply by adapter implements the interface of one object and wraps another object.
That is, implements the interface of a client class and associate adaptee class and then uses this adaptee object to invoke methods on the adaptee class.
This pattern works as a bridge between two incompatible interfaces.
Motivation behind the pattern/problem it solves?
- When you want to use an existing class, and its interface does not match the one you need - Here you create an Adapter class that acts like a bridge between these two interfaces which are not compatible.
- Think about Adapter, when you want to create a reusable class that cooperates with unrelated or unforeseen classes, means classes that are not compatible with OOB principles but you still want to make them adopt each other.
- Use the Adapter pattern when you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing everyone, An Object adapter can adapt the interface of its parent class.
Design Problem
Consider in your e-commerce application we have two payment gateways, and OLD legacy and new advanced both are not related to each other.
OLD legacy has below interface definition:
void doPayment(Account account1, Account account2);
New payment has below interface definition :
void makePayment(String mobile1, String mobile2);
The requirement is to migrate from the OLD payment gateway to the advanced new payment gateway, client will use the new payment gateway but the program 'll adopt the old gateway's business logic while serving the client with the new payment gateway.
Example and code reference : Spring 5 design pattern book
Solution design and code.
Here we are trying to make the new advanced payment gateway adaptable to our OLD payment gateway using adapter pattern, adapter class.
We have two interfaces which are not compatible to each other , AdvancedPayGateway and PaymentGateway . In our case client is going to use new AdvancedPayGateway but internally we want to use the PaymentGateway to do actual account transfer. Lets see how we can achieve this.
Code Example
Main Client class
public class AdapterPatternMain {
public static void main(String[] args) {
// our old payment gateway
PaymentGateway paymentGateway = new PaymentGatewayImpl();
//new payment gateway which is referring to the our Adapter class
AdvancedPayGateway advancedPayGateway = new AdvancedPaymentGatewayAdapter(paymentGateway);
String mobile1 = null;
String mobile2 = null;
// invoking the adapter's makePayment
advancedPayGateway.makePayment(mobile1, mobile2);
}
}
public class AdvancedPaymentGatewayAdapter implements AdvancedPayGateway {
private PaymentGateway paymentGateway;
public AdvancedPaymentGatewayAdapter(PaymentGateway paymentGateway) {
super();
this.paymentGateway = paymentGateway;
}
@Override
public void makePayment(String mobile1, String mobile2) {
System.out.println("makePayment is invoked from AdvancedPaymentGatewayAdapter");
Account account1 = null;//get account number by mobile number mobile 1
Account account2 = null;//get account number by mobile number mobile 2
paymentGateway.doPayment(account1, account2);
}
}
public class PaymentGatewayImpl implements PaymentGateway {
@Override
public void doPayment(Account account1, Account account2) {
System.out.println("Do payment using Payment Gateway");
}
}
advanced payment gateway - Target class
existing payment gateway - adaptee
adapter class - has the adaptee and it's a subclass of Target class .
Please refer the solution UML diagram below .
Example and code reference : Spring 5 design pattern book
please click here for the complete code on github.
Structure : Adapter Pattern
There are two types of Adapter pattern ,
- Class adapter pattern
- Object adapter pattern.
Class adapter pattern is achieved using multiple inheritance , however in object adapter its achieved using object composition .
Please refer both the approaches in below UML diagrams :
As Java does not support Multiple inheritance we 'll not see example of class adapter pattern in deep. Please refer above UML to understand how class adapter works using multiple inheritance in other languages who supports multiple inheritance.
Components of object adapter pattern
- Client class : Interacts with Adapter class .
- Target class/interface : This is new class which client wants to use.
- Adapter Class : This inherits the Target and use adoptee object to use inside adapters class business logic.
This adopts the interface of Adaptee to the Target interface. - Adaptee class : This has the existing functionality which is expected to reuse in adapter class. This defines the existing interface that needs adapting.
Pros and Cons
Class and Object adaptor both have different trade-offs.
Pros
- supports Open/Closed Principle.
Cons
- It's sometimes unnecessary overhead to create an adapter class instead of changing actual code directly, use it if its absolutely make sense to use it keeping decoupling in mind.
- Makes it harder to override Adaptee behavior.
Adaptor vs Decorator pattern
Both are structural design patterns, decorator pattern enhances another object without changing its interface however in the adaptor pattern adaptor class implements the interface and do respective changes in the adaptor class. Intent of the Decorator pattern is to attach the additional responsibilities to an object by wrapping it with Decorator class however intent of the Adaptor pattern is to convert an interface using the adoptar class so that both non-similar interfaces can work together.
please click here for the complete code on github.
Thanks for reading !!! Love IT Live IT Enjoy IT !!!! Happy Coding !!!