← Back to list

Python patterns for fun and profit: The Adapter Pattern — Code nomad

Introduction

The Code Nomad in Stackademic · 2025-10-06 11:51 · 0 claps · 4.5 min read paywalled
#python-programming #design-pattern-in-python #adapter-pattern
Open on Medium ↗
Wiki topics: 💻 · Programming

Python patterns for fun and profit: The Adapter Pattern — Code nomad

Picture by Castorly Stock : https://www.pexels.com/nl-nl/foto/zwarte-muurpluggen-3639031/

Picture by Castorly Stock : https://www.pexels.com/nl-nl/foto/zwarte-muurpluggen-3639031/

Introduction

The Adapter pattern is used to make one interface compatible with another. It allows objects with different, and therefore incompatible interface to work together.

If you for example want to bring an existing class into your system with an interface that doesn’t match any existing interface, and you can not modify this class, you write an adapter class to bridge the gap.

It looks like this:

The pattern consists of different parts:

  • The client has an object which implements the Subject interface.
  • The object in question is the Adapter.
  • The implementation of the operation() method in the Adapter wraps the concrete_operation in the RealSubject class.

That way we can talk to the RealSubject class using an already known interface. The Adapter class takes care of converting our method-calls for the RealSubject. Also, because this pattern is loosely coupled, changing the RealSubject should be relatively painless.

What is the difference between the Decorator and the Adapter pattern?

Purpose

Decorator: The decorator pattern is used to add behaviour to objects dynamically without modifying the source.

Adapter: Make one interface compatible with another

Use

Decorator: This pattern is used to when you want to add or extend behaviour to existing classes in a flexible and reusable way without creating a hierarchy of subclasses.

Adapter: Used to integrate an existing class with an interface which is not compatible with existing interfaces. Modifying this class is not needed if you wrap it in an Adapter.

Structure

Decorator: Creating a decorator pattern involves creating a set of decorator classes that implement the same interface as the component, thereby extending or modifying its behaviour

Adapter: Create an Adapter class, implementing the desired interface. This class also holds an instance of the class you want to adapted, the adaptee. The adapter delegates calls to the adaptee converting or transforming the input or output of these calls.

Example

Imagine having a bakery, you add things like GlazingDecorator or a WhippedCreamDecorator wrapping around your Pie-class to produces pies of the desired kind

Another classic example would be the conversion of units of measurement. If you have a classes which expects lengths to be in feet and inches, yet your client needs meters, you can wrap the classes in ConverterAdapter and have the conversion done automatically

Difference between Decorator and Adapter

In short, Adapter is used to make incompatible things work together, while the Decorator adds and extends functionality.

Implementation in Python

Preparing the stage

We will start by importing the following:

from abc import ABC, abstractmethod

Line by line:

  1. ABC stands for ‘Abstract Base Class’. When you derive from this class you simply tell Python that your class is meant to be abstract. This means that it is designed to be a template or a blueprint which should function as a baseclass, but should have no concrete implementation or instance of its own.
  2. The @abstractmethod decorator marks specific methods as abstract. This means that must and should be implemented by any concrete (i.e. non-abstract) subclass.

The target interface

We start by defining the interface of our target, that is the interface which our clients expect:

class Target(ABC):
    @abstractmethod
    def request(self) -> str:
        pass

Line by line:

  1. The Target interface derives from ABC so it is an abstract base class.
  2. It defines one abstract method called request().

The legacy service

To demonstrate the idea of an adapter, let’s define some LegacyService with a different interface:

class LegacyService:
    def specific_request(self, data: str) -> str:
        return f"LegacyService processing: {data}"

As you can see the interface of the LegacyService is different from our target.

The adapter

Since this interface is different, we need an adapter:

class ServiceAdapter(Target):
    def __init__(self, legacy_service: LegacyService):
        self._legacy_service = legacy_service

    def request(self) -> str:
        # Adapt the interface: convert Target.request() to LegacyService.specific_request()
        return self._legacy_service.specific_request("adapted data")

Line by line:

  1. The ServiceAdapter inherits from the Target interface, which means it must implement the request() method.
  2. The constructor receives an object of type LegacyService as its argument.
  3. The request() method basically redirects a call to request() to the specific_request() method on the LegacyService

The client code

All we now need is a small function to call our request() method:

def client_code(target: Target):
    return target.request()

Time to test

We can now test our adapter:

if __name__ == "__main__":
    # Client can work with adapter as if it's a Target
    legacy = LegacyService()
    adapter = ServiceAdapter(legacy)
    print(client_code(adapter))

What happens here is:

  1. We create our legacy service.
  2. We wrap it in our adapter,
  3. And call the desired functionality.

Conclusion

In conclusion, the Adapter pattern stands out as an indispensable tool in the object-oriented design toolkit, primarily serving as a vital bridge for resolving interface incompatibilities. Its function is elegantly simple yet profoundly impactful: enabling existing, potentially unmodifiable classes (the adaptee, or LegacyService in our example) to fulfill the contract of a client's expected interface (the Target).

The Python implementation effectively showcased the mechanics of this process, utilizing inheritance to conform to the Target and delegation to translate the method call for the LegacyService. This deliberate loose coupling is its greatest strength, promoting extensive code reuse and simplifying the integration of external dependencies or complex legacy systems without requiring disruptive internal modifications. The Adapter shields the client from the underlying complexity of the original service, resulting in code that is more stable and maintainable over time.

Furthermore, understanding the Adapter pattern is incomplete without clearly distinguishing it from the Decorator pattern. While the Decorator is dedicated to the dynamic addition or extension of responsibilities, the Adapter’s mission is purely one of transformation and interoperability. By encapsulating the conversion logic within a dedicated adapter class, we ensure that the client code remains clean and ignorant of the interface friction beneath it. This strategic isolation solidifies the Adapter pattern’s status as a cornerstone of flexible and resilient software architecture.

Originally published at https://codenomad.nl on October 6, 2025.

A message from our Founder

Hey, Sunil here. I wanted to take a moment to thank you for reading until the end and for being a part of this community.

Did you know that our team run these publications as a volunteer effort to over 3.5m monthly readers? We don’t receive any funding, we do this to support the community. ❤️

If you want to show some love, please take a moment to follow me on LinkedIn, TikTok, **Instagram. You can also subscribe to our [weekly newsletter](https://newsletter.plainenglish.io/)**.

And before you go, don’t forget to clap and follow the writer️!


메타데이터
post_id
cb627f17c3dc
slug
python-patterns-for-fun-and-profit-the-adapter-pattern-code-nomad-cb627f17c3dc
url
https://blog.stackademic.com/python-patterns-for-fun-and-profit-the-adapter-pattern-code-nomad-cb627f17c3dc
canonical_url
https://blog.stackademic.com/python-patterns-for-fun-and-profit-the-adapter-pattern-code-nomad-cb627f17c3dc
author_url
https://medium.com/@codenomadnl
status
ok
fetched_at
2026-07-08 08:18:29