So arbeiten Sie mit dem Decorator-Entwurfsmuster in C #

Entwurfsmuster sind Lösungen für wiederkehrende Probleme und Komplexitäten im Software-Design und werden in drei verschiedene Kategorien eingeteilt: Kreation, Struktur und Verhalten.

Das Decorator-Entwurfsmuster ist ein Strukturmuster und kann verwendet werden, um einem Objekt Funktionen dynamisch hinzuzufügen, ohne dass die Struktur des Objekts geändert werden muss. Im Wesentlichen können Sie das Decorator-Muster nutzen, um Funktionen oder Verhalten dynamisch oder statisch an ein Objekt anzuhängen, ohne dass die Struktur des Objekts geändert werden muss.

Beachten Sie, dass das Decorator-Entwurfsmuster dem Open Closed-Prinzip folgt, einem der SOLID-Prinzipien. Im Übrigen wird das Open Closed-Prinzip verwendet, um Klassen zu entwerfen, die für Erweiterungen offen, für Änderungen jedoch geschlossen sind. Die Konformität mit dem Open-Closed-Prinzip erleichtert das Erstellen von Anwendungen, die wiederverwendbar sind und problemlos gewartet werden können. Die Gang of Four (GOF) von Dofactory erklärt: "Fügen Sie einem Objekt dynamisch zusätzliche Verantwortlichkeiten hinzu. Dekorateure bieten eine flexible Alternative zur Unterklasse, um die Funktionalität zu erweitern."

Ein bisschen Code

In diesem Abschnitt werden wir untersuchen, wie wir das Decorator-Entwurfsmuster in C # implementieren können. Zu den Teilnehmern an einer typischen Implementierung des Decorator-Entwurfsmusters gehören:

  1.  Komponente - Dies ist der Basistyp des tatsächlichen oder des konkreten Typs
  2. Betonkomponente - Dies ist der Betontyp, der die Basiskomponente erweitert. Beachten Sie, dass die zusätzlichen Verantwortlichkeiten oder Funktionen in diesem Typ hinzugefügt werden.
  3. Dekorateur - Dies ist eine Referenz auf eine Komponente. Die dynamischen Funktionen werden in diesem Typ hinzugefügt.

Betrachten wir nun die folgende Klasse.

public abstract class Employee

   {

       public abstract string Display();

   }

Beachten Sie, dass Sie bei Verwendung des Decorator-Entwurfsmusters das Verhalten einer vorhandenen Klasse erweitern. Dies bedeutet jedoch nicht unbedingt, dass Sie abstrakte Typen verwenden müssen. Die Typen können abstrakt sein oder nicht. Sie können das Decorator-Entwurfsmuster auch mithilfe von Schnittstellen oder mithilfe von Methoden implementieren, die in Ihren konkreten Klassen virtuell sind. Im Wesentlichen müssen Sie bei der Implementierung des Decorator-Entwurfsmusters nicht nur abstrakte Klassen verwenden. Wir verwenden hier nur der Einfachheit halber eine abstrakte Klasse.

Die EmployeeConcrete-Klasse erweitert die Employee-Klasse und fügt ihr zusätzliche Eigenschaften hinzu. So würde diese Klasse aussehen.

   public class EmployeeConcrete : Employee

   {

       public string FirstName { set; get; }

       public string LastName { set; get; }

       public string Address { set; get; }

       public override string Display()

       {

           StringBuilder data = new StringBuilder();

           data.Append("First name: " + FirstName);

            data.Append("\nLast name: " + LastName);

           data.Append("\nAddress: " + Address);

           return data.ToString();

       }

   }

Die EmployeeDecorator-Klasse erweitert die Employee-Klasse, akzeptiert eine Instanz der Komponentenklasse mit dem Namen Employee und überschreibt die Display () -Methode. So würde diese Klasse aussehen.

public class EmployeeDecorator : Employee

   {

       Employee employee = null;

       protected EmployeeDecorator(Employee employee)

       {

           this.employee = employee;

       }

       public override string Display()

       {

           return employee.Display();

       }

   }

Nachdem die Komponente, die Betonkomponente und die Dekorationsklasse fertig sind, können Sie die EmployeeDecorator-Klasse erweitern, um eine konkrete Dekorationsklasse zu erstellen. Die folgende Codeliste zeigt, wie diese Klasse aussehen würde.

public class PermanentEmployeeDecorator : EmployeeDecorator

   {

       //Add properties relevant to a permanent employee

       private double PF { get; set; }

       public PermanentEmployeeDecorator(Employee employee) : base(employee)

       {   }

       public override string Display()

       {

           return base.Display() + "\nEmployee type: Permanent";

       }

   }

Und das ist alles was Sie tun müssen! Sie können jetzt eine Instanz von PermanentEmployeeDecorator erstellen und wie im folgenden Codeausschnitt gezeigt verwenden.

static void Main(string[] args)

       {

           EmployeeConcrete employeeConcrete = new EmployeeConcrete

         { FirstName = "Joydip", LastName = "Kanjilal", Address = "Hyderabad, India" };

           PermanentEmployeeDecorator employeeDecorator = new PermanentEmployeeDecorator(employeeConcrete);

           Console.WriteLine(employeeDecorator.Display());

           Console.Read();

       }

Sie können auch einen anderen Mitarbeitertyp haben - einen Vertragsmitarbeiter. Um es darzustellen, müssten Sie eine andere Klasse mit dem Namen ContractEmployeeDecorator erstellen, die die EmployeeDecorator-Klasse erweitert. Siehe das unten angegebene Code-Snippet.

public class ContractEmployeeDecorator : EmployeeDecorator

   {

       //Add properties relevant to a contract employee

       private double RatePerHour { get; set; }

       public ContractEmployeeDecorator(Employee employee) : base(employee)

       { }

       public override string Display()

       {

           return base.Display() + "\nEmployee type: Contractual";

       }

   }

Das folgende Codeausschnitt zeigt, wie Sie die ContractEmployeeDecorator-Klasse verwenden können.

static void Main(string[] args)

       {

           EmployeeConcrete employeeConcrete = new EmployeeConcrete

{ FirstName = "Joydip", LastName = "Kanjilal", Address = "Hyderabad, India" };

           ContractEmployeeDecorator employeeDecorator = new ContractEmployeeDecorator(employeeConcrete);

           Console.WriteLine(employeeDecorator.Display());

           Console.Read();

       }