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