Паттерн Цепочка Обязанностей (Chain of responsibility)
 
                        
                    Назначение:
Позволяет избежать привязки отправителя запроса к его получателю, давая шанс обработать запрос нескольким объектам. Связывает объекты-получатели в цепочку и передает запрос вдоль этой цепочки, пока его не обработают. «Цепочка обязанностей» является довольно распространенным паттерном в .NET Framework, хотя не все знают, что часто пользуются им. Цепочка обязанностей — это любое событие, аргументы которого позволяют уведомить инициатора, что событие обработано с помощью метода Handle() или путем установки свойства Handled в True.
Когда использовать Паттерн Chain of responsibility:
- Когда имеется более одного объекта, который может обработать определенный запрос;
- Когда надо передать запрос на выполнение одному из нескольких объект, точно не определяя, какому именно объекту;
- Когда набор объектов задается динамически.
UML схема паттерна "Цепочка Обязанностей":

Реализация шаблона "Цепочка Обязанностей" на C#:
class Program
{
    static void Main(string[] args)
    {
        Receiver receiver = new Receiver(false, true, true);
         
        PaymentHandler bankPaymentHandler = new BankPaymentHandler();
        PaymentHandler moneyPaymentHnadler = new MoneyPaymentHandler();
        PaymentHandler paypalPaymentHandler = new PayPalPaymentHandler();
        bankPaymentHandler.Successor = paypalPaymentHandler;
        paypalPaymentHandler.Successor = moneyPaymentHnadler;
 
        bankPaymentHandler.Handle(receiver);
 
        Console.Read();
    }
}
 
class Receiver
{
    // банковские переводы
    public bool BankTransfer { get; set; }
    // денежные переводы - WesternUnion, Unistream
    public bool MoneyTransfer { get; set; }
    // перевод через PayPal
    public bool PayPalTransfer { get; set; }
    public Receiver(bool bt, bool mt, bool ppt)
    {
        BankTransfer = bt;
        MoneyTransfer = mt;
        PayPalTransfer = ppt;
    }
}
abstract class PaymentHandler
{
    public PaymentHandler Successor { get; set; }
    public abstract void Handle(Receiver receiver);
}
 
class BankPaymentHandler : PaymentHandler
{
    public override void Handle(Receiver receiver)
    {
        if (receiver.BankTransfer == true)
            Console.WriteLine("Выполняем банковский перевод");
        else if (Successor != null)
            Successor.Handle(receiver);
    }
}
 
class PayPalPaymentHandler : PaymentHandler
{
    public override void Handle(Receiver receiver)
    {
        if (receiver.PayPalTransfer == true)
            Console.WriteLine("Выполняем перевод через PayPal");
        else if (Successor != null)
            Successor.Handle(receiver);
    }
}
// переводы с помощью системы денежных переводов
class MoneyPaymentHandler : PaymentHandler
{
    public override void Handle(Receiver receiver)
    {
        if (receiver.MoneyTransfer == true)
            Console.WriteLine("Выполняем перевод через системы денежных переводов");
        else if (Successor != null)
            Successor.Handle(receiver);
    }
}
Примеры в .NET Framework:
- Событие Closing в Windows Forms с возможностью отмены закрытия формы путем установки свойства Cancel аргумента CancelEventArgs в True
- Событие TaskScheduler.UnobservedException, обработчик которого может уведомить планировщик, что необработанное исключение задачи не является критическим, путем вызова метода UnobservedTaskExceptionEventArgs.SetObserved. Для аналогичных целей используются события Contract.ContractFailed и Application.DispatcherUnhandledException.
Comments:
            
            
                Please log in
                to be able add comments.
            
        
            👍
            👍
             
                    