Паттерн Цепочка Обязанностей (Chain of responsibility)
Categories:
💻 Programming
Назначение:
Позволяет избежать привязки отправителя запроса к его получателю, давая шанс обработать запрос нескольким объектам. Связывает объекты-получатели в цепочку и передает запрос вдоль этой цепочки, пока его не обработают. «Цепочка обязанностей» является довольно распространенным паттерном в .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.
👍