Verwendung des Befehlsentwurfsmusters in C #

Entwurfsmuster sind bewährte Lösungen, mit denen häufig auftretende Entwurfsprobleme gelöst und die Komplexität des Codes verringert werden. Die Designmuster der Gang of Four lassen sich in drei Kategorien einteilen:

  • Kreativ - Muster im Zusammenhang mit der Objekterstellung
  • Struktur - Muster im Zusammenhang mit der Objektmontage
  • Verhaltensmuster im Zusammenhang mit der Zusammenarbeit von Objekten und der Trennung von Verantwortlichkeiten

Das Befehlsentwurfsmuster fällt unter die Kategorie Verhaltensmuster. In diesem Artikel wird erläutert, wie wir mit dem Befehlsentwurfsmuster in C # arbeiten können.

Was ist das Befehlsentwurfsmuster?

Mit dem Befehlsentwurfsmuster soll der Anforderer einer Aktion von dem Objekt entkoppelt werden, das die Aktion ausführt. Im Befehlsentwurfsmuster wird eine Anforderung als Objekt gekapselt, das alle Informationen über die Anforderung enthält. Dieses Objekt wird dann an ein Aufruferobjekt übergeben. Das Aufruferobjekt sucht dann nach dem geeigneten Objekt, um den Befehl zu verarbeiten, und übergibt den Befehl an das Objekt.

Das Befehlsentwurfsmuster ist eine gute Wahl, wenn Sie Rückrufe, Warteschlangenaufgaben, Nachverfolgungsverlauf und Funktionen zum Rückgängigmachen / Wiederherstellen in Ihrer Anwendung implementieren möchten. Das Befehlsmuster ist eine gute Wahl für die Implementierung von Wiederholungsmechanismen, wenn Ihre Anwendung zu einem späteren Zeitpunkt erneut versuchen möchte, eine Verbindung zu einem Dienst herzustellen, der derzeit nicht betriebsbereit ist. Das Befehlsmuster wird auch in Nachrichtenwarteschlangenanwendungen verwendet, dh in Anwendungen, die nach Datenverlust wiederhergestellt werden müssen.

Teilnehmer des Befehlsentwurfsmusters

In einer klassischen Implementierung des Befehlsmusters haben Sie vier Komponenten: den Befehl, den Aufrufer, den Empfänger und den Client. Zu den Teilnehmern am Befehlsentwurfsmuster gehören:

  • Befehl - bietet eine Schnittstelle zum Ausführen einer Operation
  • ConcreteCommand - erweitert die Befehlsschnittstelle und implementiert die Execute-Methode
  • Client - Instanziiert eine ConcreteCommand-Klasse
  • Invoker - informiert den Befehl zum Ausführen der Anforderung
  • Empfänger - enthält die Logik zum Ausführen der mit der Anforderung verbundenen Operationen

Beispiel für ein Befehlsentwurfsmuster in C #

Im nächsten Abschnitt werden wir untersuchen, wie wir das Befehlsentwurfsmuster implementieren können. In unserem Beispiel implementieren wir einen einfachen Taschenrechner mit den folgenden Klassen:

  • Befehl (Befehl abstrakte Basisklasse)
  • SimpleCalculator (Empfängerklasse)
  • AddCommand (konkrete Befehlsklasse)
  • SubstractCommand (konkrete Befehlsklasse)
  • Multiplikationsbefehl (konkrete Befehlsklasse)
  • DivideCommand (konkrete Befehlsklasse)
  • Invoker (Invoker-Klasse)

Erstellen Sie die abstrakte Basisklasse Command in C #

Betrachten Sie die folgende abstrakte Basisklasse mit dem Namen Command, die die Deklaration der Execute-Methode enthält.

public abstract class Befehl

    {

        geschützter SimpleCalculator-Empfänger;

        öffentlicher Befehl (SimpleCalculator-Empfänger)

        {

            this.receiver = Empfänger;

        }}

        public abstract int Execute ();

    }}

Die folgende Aufzählung zeigt die Operationen, die in unserem einfachen Taschenrechner unterstützt werden.

öffentliche Aufzählung CommandOption

    {

        Addieren, subtrahieren, multiplizieren, teilen

    }}

Erstellen Sie die Receiver-Klasse in C #

Das Folgende ist eine Klasse namens SimpleCalculator. Diese Klasse fungiert als Empfänger und enthält die Definition der Methoden Addieren, Subtrahieren, Multiplizieren und Teilen.

öffentliche Klasse SimpleCalculator

    {

        private int _x, _y;

        öffentlicher SimpleCalculator (int a, int b)

        {

            _x = a;

            _y = b;

        }}

        public int Add ()

        {

            return _x + _y;

        }}

        public int Subtract ()

        {

            return _x - _y;

        }}

        public int Multiplizieren ()

        {

            return _x * _y;

        }}

        public int Divide ()

        {

            return _x / _y;

        }}

    }}

Erstellen Sie die konkreten Befehlsklassen in C #

Die konkreten Befehlsklassen erweitern die abstrakte Basisklasse Command und implementieren die Execute-Methode wie unten gezeigt.

 öffentliche Klasse AddCommand: Befehl

    {

        privater SimpleCalculator _calculator;

        public AddCommand (SimpleCalculator-Rechner): base (Rechner)

        {

            _calculator = Taschenrechner;

        }}

        public override int Execute ()

        {

            return _calculator.Add ();

        }}

    }}

    öffentliche Klasse SubtractCommand: Befehl

    {

        privater SimpleCalculator _calculator;

        public SubtractCommand (SimpleCalculator-Rechner):

        Basis (Taschenrechner)

        {

            _calculator = Taschenrechner;

        }}

        public override int Execute ()

        {

            return _calculator.Subtract ();

        }}

    }}

    öffentliche Klasse MultiplyCommand: Befehl

    {

        privater SimpleCalculator _calculator;

        public MultiplyCommand (SimpleCalculator-Rechner):

        Basis (Taschenrechner)

        {

            _calculator = Taschenrechner;

        }}

        public override int Execute ()

        {

            return _calculator.Multiply ();

        }}

    }}

    öffentliche Klasse DivideCommand: Befehl

    {

        privater SimpleCalculator _calculator;

        public DivideCommand (SimpleCalculator-Rechner):

        Basis (Taschenrechner)

        {

            _calculator = Taschenrechner;

        }}

        public override int Execute ()

        {

            return _calculator.Divide ();

        }}

    }}

Erstellen Sie die Invoker-Klasse in C #

Das folgende Codefragment veranschaulicht die Invoker-Klasse. Es enthält zwei Methoden, SetCommand und Execute. Während SetCommand verwendet wird, um das Befehlsobjekt der privaten Befehlsreferenz in der Invoker-Klasse zuzuweisen, wird Execute verwendet, um den Befehl auszuführen.

    Invoker der öffentlichen Klasse

    {

        privater Befehl _command;

        public void SetCommand (Befehl befehl)

        {

            _command = Befehl;

        }}

        public int Execute ()

        {

            return _command.Execute ();

        }}

    }}

Das Befehlsentwurfsmuster in Aktion in C #

Das folgende Codeausschnitt zeigt schließlich, wie Sie mit der SimpleCalculator-Klasse eine einfache Berechnung durchführen können.

statische Leere Main (string [] args)

        {

            SimpleCalculator-Rechner = neuer SimpleCalculator (15, 3);

            var addCommand = neuer AddCommand (Rechner);

            var substractCommand = neuer SubtractCommand (Rechner);

            var multiplyCommand = neuer MultiplyCommand (Rechner);

            var dividierenCommand = neuer DivideCommand (Rechner);

            Invoker invoker = neuer Invoker ();

            invoker.SetCommand (addCommand);

            Console.WriteLine ("Ergebnis ist {0}", invoker.Execute ());

            invoker.SetCommand (substractCommand);

            Console.WriteLine ("Ergebnis ist {0}", invoker.Execute ());

            invoker.SetCommand (multiplyCommand);

            Console.WriteLine ("Ergebnis ist {0}", invoker.Execute ());

            invoker.SetCommand (dividierenCommand);

            Console.WriteLine ("Ergebnis ist {0}", invoker.Execute ());

            Console.ReadLine ();

        }}

Das Befehlsentwurfsmuster bietet Unterstützung für die Erweiterbarkeit und verringert die Kopplung, die zwischen dem Aufrufer und dem Empfänger eines Befehls besteht. Da die Anforderung in ein eigenständiges Objekt gekapselt ist, können Sie Methoden mit unterschiedlichen Anforderungen parametrisieren, Anforderungen in einer Warteschlange speichern und sogar unterstützbare oder rückgängig zu machende Vorgänge unterstützen.

- -

Machen Sie mehr mit C #:

  • So arbeiten Sie mit AutoMapper in C #
  • Wann wird eine abstrakte Klasse im Vergleich zur Schnittstelle in C # verwendet?
  • So arbeiten Sie mit Threads in C #
  • Verwendung des Dapper ORM in C #
  • So implementieren Sie das Repository-Entwurfsmuster in C #
  • So implementieren Sie einen einfachen Logger in C #
  • So arbeiten Sie mit Delegierten in C #
  • So arbeiten Sie mit Action-, Func- und Predicate-Delegaten in C #
  • So arbeiten Sie mit log4net in C #
  • Wie man mit Reflexion in C # arbeitet