The Adapter Design Pattern is a structural design pattern that allows objects with incompatible interfaces to work together. It acts as a bridge between two incompatible interfaces, making them compatible and allowing them to collaborate. This pattern is especially useful when integrating new features or components into an existing system without altering its existing code.
Here’s a C# example of the Adapter Design Pattern with a use case for adapting a legacy audio player to play modern audio formats:
Create the Target Interface
Define an interface that the client code expects, but which is not currently supported by the Adaptee (legacy audio player).
public interface IAudioPlayer
{
void Play(string audioType, string filename);
}
Create the Adaptee (Legacy Audio Player)
Implement the Adaptee, which is the existing class that needs to be adapted to work with the new interface.
public class LegacyAudioPlayer
{
public void PlayMp3(string filename)
{
Console.WriteLine($"Playing MP3 file: {filename}");
}
}
Create the Adapter Class
Create an adapter class that implements the target interface (IAudioPlayer
) and uses the Adaptee class (LegacyAudioPlayer
) to provide the required functionality.
public class AudioPlayerAdapter : IAudioPlayer
{
private LegacyAudioPlayer legacyPlayer = new LegacyAudioPlayer();
public void Play(string audioType, string filename)
{
if (audioType.ToLower() == "mp3")
{
legacyPlayer.PlayMp3(filename);
}
else
{
Console.WriteLine($"Unsupported audio type: {audioType}");
}
}
}
Use Case – Playing Audio Files
Use the Adapter Design Pattern to play audio files of different formats through the IAudioPlayer
interface.
class Program
{
static void Main(string[] args)
{
IAudioPlayer audioPlayer = new AudioPlayerAdapter();
audioPlayer.Play("mp3", "song1.mp3");
audioPlayer.Play("wav", "song2.wav");
}
}
In this example, the Adapter Design Pattern allows you to use a modern IAudioPlayer
interface to play audio files even though the legacy audio player (LegacyAudioPlayer
) only supports MP3 files. The AudioPlayerAdapter
bridges the gap and adapts the legacy player to the new interface. This pattern is useful when you need to make two incompatible interfaces work together, especially when integrating old and new systems or components.