top of page

Adapter Design Pattern in the real word

The Adapter Design Pattern is a structural design pattern that allows objects with incompatible interfaces to collaborate. It acts as a bridge between two incompatible interfaces, allowing them to work together without modifying their existing code.


The Adapter Design Pattern consists of three main components:

  1. Target: This is the interface that the client expects to use.

  2. Adaptee: This is the existing interface that needs to be adapted to work with the client.

  3. Adapter: This is the class that adapts the Adaptee to the Target interface.


The Adapter pattern is used to convert the interface of one class into another interface that is compatible with the client's code. This pattern is useful when we have two incompatible interfaces and we need to make them work together. The Adapter acts as a bridge between the two interfaces and allows them to communicate with each other.

In the real world, the Adapter pattern is used in many different scenarios. Here are a few examples:

  1. Converting electrical sockets: When we travel to a different country, we often find that the electrical sockets are different from what we use in our home country. In this case, we need to use an adapter to convert the plug of our device into a plug that is compatible with the local socket.

  2. Legacy code integration: When we need to integrate legacy code into a new system, we may find that the legacy code uses an interface that is incompatible with the new system. In this case, we can use an adapter to make the legacy code work with the new system.

  3. Data format conversion: When we receive data from a third-party system, we may find that the data is in a format that is incompatible with our system. In this case, we can use an adapter to convert the data into a format that our system can understand.

  4. Third-party library integration: When we use a third-party library in our code, we may find that the library uses an interface that is incompatible with our code. In this case, we can use an adapter to make the library work with our code.

Implementing Adapter Design Pattern

Let's take an example scenario where we have a client that uses a third-party payment gateway for processing payments, but we want to integrate with a new payment gateway. However, the new payment gateway has a different API that our client does not support. In this case, we can use the adapter design pattern to create an adapter that acts as a bridge between our client and the new payment gateway.


Here are the steps to implement the adapter design pattern:


STEP 1: Identify the incompatible interfaces: In our example, the third-party payment gateway has a different API than the new payment gateway, which is not supported by our client.


STEP 2: Create a target interface: This is the interface that the client uses to communicate with the new payment gateway. In our example, we can create a new interface called PaymentGateway that defines the methods required to process payments.

public interface PaymentGateway {
    void processPayment(String paymentType, double amount);
}

STEP 3: Create an adapter: The adapter implements the target interface and adapts the incompatible interface of the new payment gateway to the target interface. In our example, we can create a NewPaymentGatewayAdapter that implements the PaymentGateway interface and adapts the new payment gateway's API to the target interface.

public class NewPaymentGatewayAdapter implements PaymentGateway {
    private NewPaymentGateway newPaymentGateway;
    
    public NewPaymentGatewayAdapter(NewPaymentGateway newPaymentGateway) {
        this.newPaymentGateway = newPaymentGateway;
    }

    @Overridepublic void processPayment(String paymentType, double amount) {
        String paymentMethod;
        if(paymentType.equals("credit")) {
            paymentMethod = "CREDIT";
        } else if(paymentType.equals("debit")) {
            paymentMethod = "DEBIT";
        } else {
            throw new RuntimeException("Invalid payment type");
        }
        
        newPaymentGateway.makePayment(amount, paymentMethod);
    }
}

STEP 4: Use the adapter: Finally, we can use the adapter to process payments through the new payment gateway using the target interface. The client can use the PaymentGateway interface to communicate with the new payment gateway without having to modify its code.

// Create a new instance of the new payment gatewayNewPaymentGateway newPaymentGateway = new NewPaymentGateway();

// Create an adapter to use the new payment gateway with the PaymentGateway interfacePaymentGateway newPaymentGatewayAdapter = new NewPaymentGatewayAdapter(newPaymentGateway);

// Use the adapter to process payments
newPaymentGatewayAdapter.processPayment("credit", 100.0);
newPaymentGatewayAdapter.processPayment("debit", 50.0);

In our example, we created an adapter to adapt the new payment gateway's API to the target interface defined by the PaymentGateway interface. This allowed our client to use the new payment gateway without having to modify its code.


Advantages of Adapter Design Pattern:

  • Provides a way to make two incompatible interfaces work together.

  • Allows reuse of existing code without modifying it.

  • Enhances reusability by making the interface of one class compatible with another.

  • Promotes separation of concerns by isolating the interface conversion code from the rest of the application logic.


Disadvantages of Adapter Design Pattern:

  • This can lead to an increase in the complexity of the code.

  • This may result in a performance overhead due to the need for extra conversions.


Usage of Adapter Design Pattern:

  • When you have existing code that needs to be reused in a new system that has a different interface.

  • When you need to integrate two existing systems that have incompatible interfaces.

  • When you want to decouple an existing system from a newly introduced system without changing the existing system’s code.


Conclusion

The adapter design pattern is a powerful pattern that allows us to adapt incompatible interfaces and integrate different systems. By following the steps outlined above and using code examples, we can easily implement the adapter design pattern in our applications. The adapter design pattern is useful in situations where there is a need to bridge the gap between two incompatible interfaces. It provides a way to reuse existing code without modifying it and promotes the separation of concerns. However, care should be taken to avoid introducing unnecessary complexity and performance overhead.

0 comments
bottom of page