Thiego Gagliardi
Thiego Gagliardi29/03/2024 06:58
Compartilhe

Design Pattern Chain of Responsibility com .Net C#

    Aproveitar padrões de design comprovados pode aumentar significativamente a eficiência e a capacidade de manutenção de nosso código. Um desses padrões é a Cadeia de Responsabilidade, que fornece uma solução elegante para gerenciar cenários complexos de fluxo de trabalho.

    O design pattern Chain of Responsibility é um design pattern comportamental que permite que uma solicitação seja passada ao longo de uma cadeia de manipuladores em potencial até encontrar o apropriado para processá-la. Cada manipulador da cadeia tem autonomia para tratar a solicitação ou delegá-la ao próximo manipulador. Essa abordagem dissociada promove flexibilidade, escalabilidade e capacidade de manutenção em cenários de gerenciamento de fluxo de trabalho. Como muitos outros padrões de design comportamental, a Cadeia de Responsabilidade depende da transformação de comportamentos específicos em objetos independentes chamados manipuladores.

    using System;
    
    // Handler interface
    public interface ISupportHandler
    {
      void SetNextHandler(ISupportHandler handler);
      void HandleTicket(Ticket ticket);
    }
    
    // Abstract base class for concrete handlers
    public abstract class SupportHandlerBase : ISupportHandler
    {
      private ISupportHandler _nextHandler;
    
      public void SetNextHandler(ISupportHandler handler)
      {
          _nextHandler = handler;
      }
    
      public virtual void HandleTicket(Ticket ticket)
      {
          // If this handler can handle the ticket, do the handling
          if (CanHandleTicket(ticket))
          {
              Handle(ticket);
          }
          // If there is a next handler, pass the ticket to it
          else if (_nextHandler != null)
          {
              _nextHandler.HandleTicket(ticket);
          }
          // No handler in the chain can handle the ticket
          else
          {
              Console.WriteLine("Ticket cannot be handled.");
          }
      }
    
      protected abstract bool CanHandleTicket(Ticket ticket);
      protected abstract void Handle(Ticket ticket);
    }
    
    // Concrete handler: Level 1 Support
    public class Level1SupportHandler : SupportHandlerBase
    {
      protected override bool CanHandleTicket(Ticket ticket)
      {
          return ticket.Severity == Severity.Low;
      }
    
      protected override void Handle(Ticket ticket)
      {
          Console.WriteLine("Level 1 Support handles the ticket.");
          // Handle the ticket at Level 1 Support
      }
    }
    
    // Concrete handler: Level 2 Support
    public class Level2SupportHandler : SupportHandlerBase
    {
      protected override bool CanHandleTicket(Ticket ticket)
      {
          return ticket.Severity == Severity.Medium;
      }
    
      protected override void Handle(Ticket ticket)
      {
          Console.WriteLine("Level 2 Support handles the ticket.");
          // Handle the ticket at Level 2 Support
      }
    }
    
    // Concrete handler: Level 3 Support
    public class Level3SupportHandler : SupportHandlerBase
    {
      protected override bool CanHandleTicket(Ticket ticket)
      {
          return ticket.Severity == Severity.High;
      }
    
      protected override void Handle(Ticket ticket)
      {
          Console.WriteLine("Level 3 Support handles the ticket.");
          // Handle the ticket at Level 3 Support
      }
    }
    
    // Ticket class
    public class Ticket
    {
      public Severity Severity { get; set; }
      // Other ticket properties
    }
    
    // Enum representing severity levels of tickets
    public enum Severity
    {
      Low,
      Medium,
      High
    }
    
    // Usage example
    public class Program
    {
      public static void Main()
      {
          // Create the support handlers
          var level3SupportHandler = new Level3SupportHandler();
          var level2SupportHandler = new Level2SupportHandler();
          var level1SupportHandler = new Level1SupportHandler();
    
          // Set the chain of responsibility
          level1SupportHandler.SetNextHandler(level2SupportHandler);
          level2SupportHandler.SetNextHandler(level3SupportHandler);
    
          // Create tickets
          var ticket1 = new Ticket { Severity = Severity.Low };
          var ticket2 = new Ticket { Severity = Severity.Medium };
          var ticket3 = new Ticket { Severity = Severity.High };
    
          // Process the tickets
          level1SupportHandler.HandleTicket(ticket1);
          level1SupportHandler.HandleTicket(ticket2);
          level1SupportHandler.HandleTicket(ticket3);
      }
    }
    

    Neste exemplo de código, temos os seguintes componentes:

    A interface ISupportHandler define o contrato para manipuladores de suporte, especificando o método SetNextHandler para definir o próximo manipulador na cadeia e o método HandleTicket para manipular um ticket de suporte. A classe abstrata SupportHandlerBase fornece uma implementação básica para manipuladores concretos. Ele contém a referência para o próximo manipulador na cadeia e fornece a implementação padrão do método HandleTicket.

    Os manipuladores concretos estendem essa classe base e implementam os métodos CanHandleTicket e Handle com base em seus critérios específicos. As classes manipuladoras concretas (Level1SupportHandler, Level2SupportHandler e Level3SupportHandler) herdam da classe SupportHandlerBase. Eles substituem o método CanHandleTicket para definir seus critérios para lidar com um ticket e implementam o método Handle para realizar o gerenciamento real do ticket. A classe Ticket representa um ticket de suporte ao cliente e inclui uma propriedade Severity para indicar o nível de gravidade do ticket. A enumeração Severidade representa os níveis de gravidade dos tickets. No método Main, criamos instâncias das classes manipuladoras de suporte e definimos a cadeia de responsabilidade chamando o método SetNextHandler. Também criamos três tickets com diferentes níveis de gravidade e os passamos para o primeiro manipulador da cadeia usando o método HandleTicket.

    Fonte : https://mohamed-hendawy.medium.com/chain-of-responsibility-design-pattern-in-c-with-examples-d87da6e5ead

    Compartilhe
    Comentários (0)