Menu
Coddy logo textTech

Adaptermuster

Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 57 von 70.

Das Adapter-Muster ist ein strukturelles Muster, das inkompatiblen Schnittstellen ermöglicht, zusammenzuarbeiten. Es fungiert als Brücke zwischen zwei Klassen und wandelt die Schnittstelle einer Klasse in eine Schnittstelle um, die Clients erwarten. Stell es dir wie einen Netzadapter vor, mit dem du ein europäisches Gerät an eine amerikanische Steckdose anschließen kannst.

Dieses Muster ist besonders nützlich, wenn du eine vorhandene Klasse verwenden möchtest, deren Schnittstelle jedoch nicht dem entspricht, was dein Code benötigt. Anstatt die ursprüngliche Klasse zu ändern (auf die du möglicherweise keinen Einfluss hast), erstellst du einen Adapter, der sie kapselt:

// Bestehende Klasse mit inkompatibler Schnittstelle
public class OldPrinter
{
    public void PrintMessage(string msg) => Console.WriteLine($"Old: {msg}");
}

// Schnittstelle, die Ihr Code erwartet
public interface IPrinter
{
    void Print(string text);
}

// Adapter überbrückt die Lücke
public class PrinterAdapter : IPrinter
{
    private OldPrinter _oldPrinter;
    
    public PrinterAdapter(OldPrinter oldPrinter)
    {
        _oldPrinter = oldPrinter;
    }
    
    public void Print(string text)
    {
        _oldPrinter.PrintMessage(text);  // Delegiert an die alte Schnittstelle
    }
}

Jetzt kann Ihr Code über die erwartete Schnittstelle mit dem alten Drucker arbeiten:

OldPrinter legacy = new OldPrinter();
IPrinter printer = new PrinterAdapter(legacy);

printer.Print("Hello");  // Alt: Hello

Das Adapter-Muster ist bei der Integration von Bibliotheken von Drittanbietern oder Legacy-Code in deine Anwendung von unschätzbarem Wert. Der Client-Code arbeitet mit der Schnittstelle IPrinter, ohne zu wissen, dass eine alte, inkompatible Klasse im Hintergrund tatsächlich die Arbeit erledigt.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Mediaplayer-System mithilfe des Adapter-Patterns. Du hast eine vorhandene Audiobibliothek, die MP3-Dateien abspielt, aber deine Anwendung benötigt eine einheitliche Schnittstelle, die verschiedene Medientypen verarbeiten kann. Du erstellst einen Adapter, der diese Lücke überbrückt, sodass dein moderner Mediaplayer nahtlos mit der älteren Audiobibliothek zusammenarbeiten kann.

Du organisierst deinen Code über drei Dateien:

  • LegacyAudio.cs: Dies stellt eine vorhandene Bibliothek dar, die du nicht ändern kannst. Erstelle eine LegacyAudioPlayer-Klasse im Namespace MediaSystem mit einer Methode PlayMp3(string filename), die den String "Playing MP3: {filename}" zurückgibt. Dies ist dein „Adaptee“ – die Klasse mit der inkompatiblen Schnittstelle.
  • MediaAdapter.cs: Erstelle die Schnittstelle und den Adapter im selben Namespace. Definiere eine IMediaPlayer-Schnittstelle mit einer Methode Play(string filename), die einen String zurückgibt. Erstelle anschließend eine MediaPlayerAdapter-Klasse, die IMediaPlayer implementiert. Dein Adapter sollte eine LegacyAudioPlayer-Instanz umschließen, die über den Konstruktor übergeben wird, und den Aufruf von Play in einen Aufruf der Methode PlayMp3 des älteren Players übersetzen.
  • Program.cs: Führe alles zusammen, indem du den älteren Player erstellst, ihn in deinen Adapter einbindest und den Adapter über die IMediaPlayer-Schnittstelle verwendest. Dies zeigt, wie Client-Code mit der modernen Schnittstelle arbeiten kann, während der Adapter die Kommunikation mit dem älteren System im Hintergrund übernimmt.

Du erhältst eine Eingabe:

  • Der abzuspielende Dateiname (z. B. song.mp3)

Erstelle einen LegacyAudioPlayer, binde ihn in einen MediaPlayerAdapter ein, rufe anschließend Play über die IMediaPlayer-Schnittstelle auf dem Adapter auf und gib das Ergebnis aus.

Wenn die Eingabe beispielsweise favorite_track.mp3 lautet, sollte die Ausgabe folgendermaßen aussehen:

Playing MP3: favorite_track.mp3

Das Schöne an diesem Pattern ist, dass dein Hauptcode nur mit IMediaPlayer interagiert – er weiß nicht, dass eine ältere Audiobibliothek die eigentliche Arbeit erledigt. Wenn du später eine andere ältere Bibliothek unterstützen musst, erstellst du einfach einen neuen Adapter, ohne Client-Code ändern zu müssen!

Probier es selbst

using System;
using MediaSystem;

class Program
{
    public static void Main(string[] args)
    {
        // Lies die Dateinamen-Eingabe ein
        string filename = Console.ReadLine();
        
        // TODO: Erstelle eine LegacyAudioPlayer-Instanz
        
        // TODO: Umschließe sie mit einem MediaPlayerAdapter
        
        // TODO: Verwende den Adapter über das IMediaPlayer-Interface
        // und gib das Ergebnis des Aufrufs von Play mit dem Dateinamen aus
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C#-Compiler