Adapter Pattern: Power Plug Adapter

The Adapter Pattern helps you connect things that were never meant to work together. Sometimes you have existing code or systems that cannot be changed, but you still want them to talk to each other. Rather than rewriting one or both, you create an adapter as a bridge.

This pattern is especially helpful when combining old software with new, or when you use third-party libraries that do not match your code. It acts like a plug converter when travelling to another country—making everything compatible, without changing the original parts.

Real-Life Analogy: Power Plug Adapter

Imagine you travel from the UK to Europe and need to charge your phone. The wall socket is different, and your UK plug doesn't fit. You don't buy a new charger — you use a plug adapter. It converts your UK plug into the shape that fits the European socket.

In code, the Adapter Pattern works the same way. You already have something that works — you just need to make it compatible with another system.

Power plug adapter converting one type of plug into another
Like using a travel plug adapter, the Adapter Pattern helps two different systems work together by translating between them.

Benefits of Adapter Pattern

You often work with code you can't change — like third-party libraries or legacy systems. The Adapter Pattern lets you keep your existing code and still use it in new ways.

It helps you avoid rewriting or replacing existing classes.

  • Connects incompatible interfaces
  • Improves reuse of existing classes
  • Protects client code from changes in third-party APIs

What to Implement

To implement the Adapter Pattern, you need:

A target interface (what your code expects), an existing class that doesn't match, and an adapter that connects the two.

  • Target Interface: Defines the expected behaviour
  • Adaptee: The existing class with a different interface
  • Adapter: Converts the adaptee into the target format

How It Works in C#


// Target Interface
public interface ICharger
{
    void Charge();
}

// Adaptee
public class EuropeanSocket
{
    public void ProvidePower() => Console.WriteLine("Power from EU socket");
}

// Adapter
public class UkToEuAdapter : ICharger
{
    private readonly EuropeanSocket _socket = new();

    public void Charge()
    {
        Console.WriteLine("Using adapter to connect UK plug to EU socket");
        _socket.ProvidePower();
    }
}

Usage:


ICharger charger = new UkToEuAdapter();
charger.Charge();

When Should You Use It?

Use the Adapter Pattern when your code expects one interface but gets another. It's a perfect fit when you want to reuse existing code that doesn't quite match your new design.

Common use cases include:

  • Working with legacy code
  • Integrating with third-party systems
  • Bridging different libraries

When Not to Use It: Avoid adapters if both systems already share a common base or could be easily updated to work together directly.

Where Is It Used in the Real World?

The Adapter Pattern is found in nearly every integration project. It is especially useful for making old code work with new systems, or bridging two third-party APIs together.

  • Legacy system integration (making old code work with new APIs)
  • Cross-platform software (bridging platform-specific features)
  • Hardware abstraction layers (drivers, hardware-software adapters)
  • Third-party library integration (adapting library interfaces for your needs)

Final Thoughts

The Adapter Pattern helps you plug old things into new systems — or vice versa — without breaking anything. It's like a travel adapter for your code: quick, simple, and extremely useful when dealing with things outside your control.