Как да работите с дизайна на декоратора в C #

Моделите на проектиране са решения на повтарящи се проблеми и сложности в софтуерния дизайн и се класифицират в три отделни категории: творчески, структурни и поведенчески.

Шаблонът за дизайн на Decorator е структурен модел и може да се използва за добавяне на функционалност към обект, динамично отменящ необходимостта от промяна на структурата на обекта. По същество можете да използвате модела на декоратора, за да придадете функционалност или поведение на обект динамично или статично, без да се нуждаете от промяна на структурата на обекта.

Имайте предвид, че моделът на декоратора следва Отворения затворен принцип, един от принципите на ТВЪРДОТО. Между другото, Отвореният затворен принцип се използва за проектиране на класове, които са отворени за разширения, но затворени за модификации. Съответствието с отворения затворен принцип улеснява изграждането на приложения, които могат да се използват многократно и могат лесно да се поддържат. Бандата на четирите (GOF) в Dofactory гласи: "Придайте допълнителни отговорности на обект динамично. Декораторите предоставят гъвкава алтернатива на подкласирането за разширяване на функционалността."

Малко код

В този раздел ще разгледаме как можем да приложим шаблона за дизайн на Decorator в C #. Участниците в типично изпълнение на дизайна на декоратора включват:

  1.  Компонент - това представлява основния тип на действителния или конкретния тип
  2. Бетонен компонент - това представлява конкретния тип, който разширява основния компонент. Имайте предвид, че допълнителните отговорности или функционалности се добавят към този тип.
  3. Декоратор - това представлява препратка към компонент. В този тип се добавят динамичните функционалности.

Сега, нека разгледаме следния клас.

public abstract class Employee

   {

       public abstract string Display();

   }

Имайте предвид, че когато използвате шаблона за дизайн на Decorator, вие разширявате поведението на съществуващ клас, но това не означава непременно, че трябва да използвате абстрактни типове - типовете могат или не могат да бъдат абстрактни. Можете също така да приложите шаблона за дизайн на Decorator, като използвате интерфейси или дори като използвате методи, които са виртуални във вашите конкретни класове. По същество не сте ограничени да използвате само абстрактни класове, когато внедрявате шаблона за дизайн на Decorator. Тук използваме абстрактен клас само за простота.

Класът EmployeeConcrete разширява класа Employee и добавя допълнителни свойства към него. Ето как би изглеждал този клас.

   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();

       }

   }

Класът EmployeeDecorator разширява класа Employee, приема екземпляр на класа компонент с име Employee и отменя метода Display (). Ето как би изглеждал този клас.

public class EmployeeDecorator : Employee

   {

       Employee employee = null;

       protected EmployeeDecorator(Employee employee)

       {

           this.employee = employee;

       }

       public override string Display()

       {

           return employee.Display();

       }

   }

Сега, когато компонентът, бетонният компонент и класът на декоратора са готови, вече можете да разширите класа EmployeeDecorator, за да създадете клас на декоратор на бетон. Следният списък с кодове показва как би изглеждал този клас.

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";

       }

   }

И това е всичко, което трябва да направите! Вече можете да създадете екземпляр на PermanentEfficieeDecorator и да го използвате, както е показано в кодовия фрагмент по-долу.

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();

       }

Можете да имате и друг тип служител - договорно нает служител. За да го представите, ще трябва да създадете друг клас с име ContractEfficieeDecorator, който разширява класа EmployeeDecorator. Обърнете се към кодовия фрагмент, даден по-долу.

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";

       }

   }

Следният кодов фрагмент илюстрира как можете да използвате класа ContractEfficieeDecorator.

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();

       }