What is Adapter Pattern in C#?
Tags: csharp
Published: 2024-01-23 12:01:33

The Adapter Pattern is a popular design pattern used in C# to facilitate communication between incompatible interfaces. It acts as a bridge between two interfaces, allowing them to work together seamlessly by converting the interface of one class into another form that clients expect.

In simpler terms, the Adapter Pattern helps two classes with incompatible interfaces to work together without the need for extensive code modifications. It allows integration of new classes without modifying the existing source code, enhancing flexibility, reusability, and maintainability.

Let's consider a scenario where we have an existing Weather API that retrieves weather data from a third-party service. The API provides methods to fetch current weather conditions of a location in a specific format. However, we want to use a different weather service that provides the same data but in a different format.

In this scenario, we can use the Adapter Pattern to create a new class that adapts the interface of the new weather service to match the interface expected by our existing Weather API. Here's an example implementation in C#:

```csharp
// Existing Weather API
public interface IWeatherService
{
    string GetTemperature(string location);
    string GetHumidity(string location);
}

public class WeatherService : IWeatherService
{
    public string GetTemperature(string location)
    {
        // Implementation to fetch temperature from third-party service
        return "Temperature: 25°C";
    }

    public string GetHumidity(string location)
    {
        // Implementation to fetch humidity from third-party service
        return "Humidity: 60%";
    }
}

// New Weather Service
public class NewWeatherService
{
    public string GetCurrentWeather(string location)
    {
        // Implementation to fetch weather data from new service
        return "Temperature: 25°C, Humidity: 60%";
    }
}

// Adapter
public class WeatherServiceAdapter : IWeatherService
{
    private readonly NewWeatherService _newWeatherService;

    public WeatherServiceAdapter(NewWeatherService newWeatherService)
    {
        _newWeatherService = newWeatherService;
    }

    public string GetTemperature(string location)
    {
        string weatherData = _newWeatherService.GetCurrentWeather(location);
        return ParseTemperature(weatherData);
    }

    public string GetHumidity(string location)
    {
        string weatherData = _newWeatherService.GetCurrentWeather(location);
        return ParseHumidity(weatherData);
    }

    private string ParseTemperature(string weatherData)
    {
        // Parse temperature from weather data
        return "Temperature: 25°C";
    }

    private string ParseHumidity(string weatherData)
    {
        // Parse humidity from weather data
        return "Humidity: 60%";
    }
}

// Usage
static void Main(string[] args)
{
    NewWeatherService newWeatherService = new NewWeatherService();
    IWeatherService weatherService = new WeatherServiceAdapter(newWeatherService);

    string temperature = weatherService.GetTemperature("New York");
    string humidity = weatherService.GetHumidity("New York");

    Console.WriteLine(temperature); // Output: Temperature: 25°C
    Console.WriteLine(humidity); // Output: Humidity: 60%
}
```

In this example, we have an existing `WeatherService` class that implements the `IWeatherService` interface. We have a new weather service represented by the `NewWeatherService` class, which provides the same weather data but using a different method (`GetCurrentWeather`) to retrieve it.

To adapt the new weather service to the existing interface, we create a `WeatherServiceAdapter` class that implements `IWeatherService`. The adapter takes an instance of `NewWeatherService` in its constructor and adapts its methods to match the `IWeatherService` interface.

By using the Adapter Pattern, we can now seamlessly integrate the new weather service into our existing codebase without changing the code that relies on the `IWeatherService` interface. This allows for easy switching between different weather services in the future, enhancing the flexibility and maintainability of the code.