Skip to content

Adapter Pattern: Integrating Incompatible Systems

Adapter Pattern: Integrating Incompatible Systems

The Adapter Pattern is a structural design pattern that allows objects with incompatible interfaces to collaborate. It acts as a wrapper that converts one interface into another.

🏗️ The Problem

Imagine you are building a Weather Application that expects data in XML format. You find a great third-party Weather API, but it only returns data in JSON format. Instead of rewriting your entire app, you can use an Adapter.

🚀 The .NET Implementation

In .NET, the Adapter pattern is essential when working with legacy code or third-party libraries.

1. The Target Interface (What your app expects)

public interface IWeatherProvider
{
    string GetWeatherXml();
}

2. The Adaptee (The incompatible third-party service)

public class ThirdPartyWeatherService
{
    public string GetWeatherJson()
    {
        return "{ 'temp': 22, 'condition': 'Sunny' }";
    }
}

3. The Adapter (The bridge)

public class WeatherAdapter : IWeatherProvider
{
    private readonly ThirdPartyWeatherService _thirdPartyService;

    public WeatherAdapter(ThirdPartyWeatherService thirdPartyService)
    {
        _thirdPartyService = thirdPartyService;
    }

    public string GetWeatherXml()
    {
        // 1. Get the JSON from the third-party service
        var json = _thirdPartyService.GetWeatherJson();
        
        // 2. CONVERT JSON TO XML (Simulated logic)
        // In reality, use System.Text.Json or Newtonsoft.Json
        Console.WriteLine($"[ADAPTER]: Converting JSON to XML...");
        return "<weather><temp>22</temp><cond>Sunny</cond></weather>";
    }
}

🛠️ Real-World Usage (Client)

// The client only knows about IWeatherProvider (XML)
IWeatherProvider provider = new WeatherAdapter(new ThirdPartyWeatherService());

// This will now internally call the JSON service but return XML!
var result = provider.GetWeatherXml();

💡 Why use Adapter?

  • Legacy Integration: Integrate new services into old codebases without changing existing logic.
  • Third-Party Libraries: Wrap external libraries to protect your app from breaking changes in those libraries.
  • Single Responsibility: The conversion logic is isolated in the Adapter class.