Adapter Pattern

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 9

Adapter Pattern

Figure 1: Design Patterns


Intent

Convert the interface of a class into another interface clients expect. Adapter lets classes
work together that couldn’t otherwise because of incompatible interfaces.
It is also Known as Wrapper.

Motivation

Sometimes a toolkit class that's designed for reuse isn't reusable only because its interface
doesn't match the domain-specific interface an application requires.

Example: Integrating Third-Party Payment Gateways

Imagine you are developing an e-commerce application that needs to process payments.
Your application supports a specific payment gateway interface that includes methods like

 processPayment()
 refundPayment()
However, you want to integrate multiple third-party payment gateways into your system,
each with its own unique interface.
Let's say you want to integrate two different payment gateways: Gateway A and Gateway B.
These gateways have different methods and data structures for processing payments:
Gateway A:

 charge(amount: float)
 voidTransaction(transactionId: int)
Gateway B:

 makePayment(total: double)
 revertTransaction(transId: long)
Your existing payment processing interface in your application:
// Existing payment gateway interface
public interface PaymentGateway
{
void processPayment(double amount);
void refundPayment(int transactionId);
}

To integrate these third-party gateways into your application, you can use the Adapter
pattern:
1. Create adapters for each third-party payment gateway that implement your
PaymentGateway interface:

// Adapter for Gateway A


public class GatewayAAdapter implements PaymentGateway
{
private GatewayA gatewayAInstance;

public GatewayAAdapter(GatewayA gatewayAInstance)


{
this.gatewayAInstance = gatewayAInstance;
}

@Override
public void processPayment(double amount)
{
gatewayAInstance.charge(amount);
}

@Override
public void refundPayment(int transactionId)
{
gatewayAInstance.voidTransaction(transactionId);
}
}

// Adapter for Gateway B


public class GatewayBAdapter implements PaymentGateway
{
private GatewayB gatewayBInstance;

public GatewayBAdapter(GatewayB gatewayBInstance)


{
this.gatewayBInstance = gatewayBInstance;
}

@Override
public void processPayment(double amount)
{
gatewayBInstance.makePayment(amount);
}

@Override
public void refundPayment(int transactionId)
{
gatewayBInstance.revertTransaction(transactionId);
}
}

2. Now you can use these adapters to seamlessly integrate the third-party gateways
into your application without changing your existing payment processing code:
// Client code
public class ECommerceApp
{
public static void processPaymentWithGateway(PaymentGateway
paymentGateway, double amount)
{
paymentGateway.processPayment(amount);
// Additional processing logic
}

public static void refundPaymentWithGateway(PaymentGateway


paymentGateway, int transactionId)
{
paymentGateway.refundPayment(transactionId);
// Additional processing logic
}
public static void main(String[] args)
{
// Integrate Gateway A
GatewayA gatewayAInstance = new GatewayA();

// Actual instance of Gateway A


GatewayAAdapter gatewayAAdapter = new
GatewayAAdapter(gatewayAInstance);

processPaymentWithGateway(gatewayAAdapter, 100.0);
refundPaymentWithGateway(gatewayAAdapter, 12345);

// Integrate Gateway B
GatewayB gatewayBInstance = new GatewayB();

// Actual instance of Gateway B


GatewayBAdapter gatewayBAdapter = new
GatewayBAdapter(gatewayBInstance);

processPaymentWithGateway(gatewayBAdapter, 200.0);
refundPaymentWithGateway(gatewayBAdapter, 67890);
}
}
Applicability

Use the Adapter pattern when:

 you want to use an existing class, and its interface does not match the one you need.
 you want to create a reusable class that cooperates with unrelated unforeseen
classes, that is, classes that don't necessarily have compatible interfaces.
 (object adapter only) you need to use several existing subclasses, but it's unpractical
to adapt their interface by subclassing every one. An object adapter can adapt the
interface of its parent class

Structure
Participants

1. Target (PaymentGateway interface):

2. Client (ECommerceApp class):


o Collaborates with objects conforming to the Target interface. The client code
in the ECommerceApp class uses the PaymentGateway interface to process
payments and refunds without directly interacting with the third-party
payment gateways.
3. Adaptee (GatewayA and GatewayB classes):
o Defines an existing interface that needs adapting. In the example, GatewayA
and GatewayB represent the existing third-party payment gateways with their
unique interfaces that are incompatible with the PaymentGateway interface.
4. Adapter (GatewayAAdapter and GatewayBAdapter classes):
o Adapts the interface of the Adaptee to the Target interface. In the example,
GatewayAAdapter and GatewayBAdapter classes implement the
PaymentGateway interface, and they internally delegate calls to the
respective methods of GatewayA and GatewayB classes.

You might also like