How to Understand Adapter Patterns with Example

The Adapter Pattern allows incompatible interfaces to work together by creating a bridge between them. It converts the interface of one class into another interface that clients expect. To understand the Adapter Pattern better, let’s look at an example:

class Target:
    def request(self):
        pass

class Adaptee:
    def specific_request(self):
        return "Adaptee's specific request"

class Adapter(Target):
    def __init__(self, adaptee):
        self.adaptee = adaptee

    def request(self):
        return self.adaptee.specific_request()

In this example, we have three classes: Target, Adaptee, and Adapter.

  • The Target class defines the interface that the client expects. It includes a request() method that the client will use.

  • The Adaptee class is the existing class with an incompatible interface. It has a specific_request() method that the client cannot directly use.

  • The Adapter class bridges the gap between the Target and Adaptee. It implements the Target interface and internally uses an instance of the Adaptee class to fulfill the request.

Here’s how you can use the Adapter Pattern:

adaptee = Adaptee()
adapter = Adapter(adaptee)
print(adapter.request())  # Output: Adaptee's specific request

In this code, we create an instance of the Adaptee class and pass it to the Adapter constructor. The Adapter object is then used as a Target object, allowing the client to call the request() method. Internally, the Adapter object delegates the request to the Adaptee object by calling its specific_request() method.

The Adapter Pattern helps in scenarios where you have existing code or third-party libraries with incompatible interfaces that you need to integrate into your system. By creating an adapter, you can make the existing code work seamlessly with your client code without modifying the original code.

Remember, the Adapter Pattern is just one of many design patterns that can be used to solve specific problems. It promotes loose coupling and allows for flexibility and extensibility in your codebase.