Menu
Coddy logo textTech

Command-Muster

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 94 von 110.

Das Command-Muster kapselt eine Anfrage als Objekt und ermöglicht es dir, Clients mit verschiedenen Anfragen zu parametrisieren, Vorgänge in eine Warteschlange zu stellen oder eine Rückgängig-Funktion zu unterstützen. Anstatt eine Methode direkt aufzurufen, verpackst du die Aktion in ein Befehlsobjekt, das gespeichert, weitergegeben oder später ausgeführt werden kann.

Das Muster umfasst drei zentrale Komponenten: eine Command-Schnittstelle mit einer execute-Methode, Concrete Commands, die bestimmte Aktionen implementieren, und einen Receiver, der die eigentliche Arbeit ausführt. Ein optionaler Invoker löst Befehle aus, ohne zu wissen, was sie tun:

abstract class Command {
  void execute();
}

class Light {
  void turnOn() => print('Light is ON');
  void turnOff() => print('Light is OFF');
}

class TurnOnCommand implements Command {
  final Light light;
  TurnOnCommand(this.light);

  @override
  void execute() => light.turnOn();
}

class TurnOffCommand implements Command {
  final Light light;
  TurnOffCommand(this.light);

  @override
  void execute() => light.turnOff();
}

class RemoteControl {
  Command? _command;

  void setCommand(Command command) {
    _command = command;
  }

  void pressButton() {
    _command?.execute();
  }
}

void main() {
  var light = Light();
  var remote = RemoteControl();

  remote.setCommand(TurnOnCommand(light));
  remote.pressButton();  // Licht ist AN

  remote.setCommand(TurnOffCommand(light));
  remote.pressButton();  // Licht ist AUS
}

Die RemoteControl weiß nichts über Lichter – sie führt einfach jeden Befehl aus, der ihr übergeben wird. Diese Entkopplung erleichtert das Hinzufügen neuer Befehle, ohne den Aufrufer ändern zu müssen. Das Command-Muster eignet sich ideal für die Implementierung von Rückgängig-/Wiederholen-Systemen, Aufgabenwarteschlangen oder Makroaufzeichnungen, bei denen Aktionen als Objekte erster Klasse behandelt werden müssen.

challenge icon

Aufgabe

Einfach

Erstelle ein Befehlsystem für einen Texteditor mit dem Command-Pattern! Du erstellst ein System, das Textoperationen als Befehlsobjekte kapselt, sodass ein Editor verschiedene Aktionen ausführen kann, ohne die Details der einzelnen Operationen zu kennen. Dies ist ein klassischer Anwendungsfall für das Command-Pattern – stell es dir wie ein Rückgängig-/Wiederholen-System vor, bei dem jede Aktion als Objekt gespeichert wird.

Du organisierst deinen Code in zwei Dateien:

  • commands.dart: Erstelle hier dein Befehlsystem. Beginne mit einer abstrakten Klasse Command, die eine execute()-Methode deklariert. Erstelle dann eine TextDocument-Klasse (den Empfänger), die ein String content-Feld (anfangs leer) enthält und drei Methoden besitzt:
    • append(String text) – fügt Text am Ende des Inhalts hinzu
    • clear() – setzt den Inhalt auf eine leere Zeichenkette
    • show() – gibt Document: [content] aus
    Implementiere nun drei konkrete Befehle, die mit einem TextDocument arbeiten:
    • AppendCommand – erhält in seinem Konstruktor ein Dokument und Text und hängt den Text bei der Ausführung an
    • ClearCommand – erhält in seinem Konstruktor ein Dokument und leert es bei der Ausführung
    • ShowCommand – erhält in seinem Konstruktor ein Dokument und zeigt dessen Inhalt bei der Ausführung an
    Erstelle schließlich eine TextEditor-Klasse (den Aufrufer), die eine Liste von Befehlen speichert. Sie sollte eine addCommand(Command command)-Methode zum Einreihen von Befehlen und eine runAll()-Methode besitzen, die alle eingereihten Befehle der Reihe nach ausführt.
  • main.dart: Importiere deine Befehlsdatei und demonstriere das Command-Pattern. Erstelle ein TextDocument und einen TextEditor. Reiht die folgenden Befehle in dieser Reihenfolge ein: Hello anhängen, World anhängen, das Dokument anzeigen, ! anhängen, es erneut anzeigen, das Dokument leeren und es ein letztes Mal anzeigen. Führe dann alle eingereihten Befehle aus.

Beachte, dass der TextEditor nichts über das Anhängen, Leeren oder Anzeigen weiß – er führt einfach die Befehle aus, die ihm übergeben werden. Diese Entkopplung ist das Wesentliche des Command-Patterns!

Erwartete Ausgabe:

Document: Hello World
Document: Hello World!
Document: 

Probier es selbst

import 'commands.dart';

void main() {
  // TODO: Erstelle eine TextDocument-Instanz

  // TODO: Erstelle eine TextEditor-Instanz

  // TODO: Reihe die folgenden Befehle in dieser Reihenfolge ein:
  // 1. Hänge "Hello" an
  // 2. Hänge " World" an
  // 3. Zeige das Dokument an
  // 4. Hänge "!" an
  // 5. Zeige das Dokument erneut an
  // 6. Leere das Dokument
  // 7. Zeige das Dokument ein letztes Mal an

  // TODO: Führe alle eingereihten Befehle 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-Dart-Compiler