Цепочка обязанностей (Chain of Responsibility) — различия между версиями
Admin (обсуждение | вклад) (→Описание) |
Admin (обсуждение | вклад) (→Пример) |
||
Строка 24: | Строка 24: | ||
=== Пример === | === Пример === | ||
<source lang="Csharp"> | <source lang="Csharp"> | ||
+ | class MainApp | ||
+ | { | ||
+ | static void Main() | ||
+ | { | ||
+ | // Setup Chain of Responsibility | ||
+ | Handler h1 = new ConcreteHandler1(); | ||
+ | Handler h2 = new ConcreteHandler2(); | ||
+ | Handler h3 = new ConcreteHandler3(); | ||
+ | h1.SetSuccessor(h2); | ||
+ | h2.SetSuccessor(h3); | ||
+ | |||
+ | // Generate and process request | ||
+ | int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 }; | ||
+ | |||
+ | h1.HandleRequest(2); | ||
+ | h1.HandleRequest(22); | ||
+ | h1.HandleRequest(222); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | abstract class Handler | ||
+ | { | ||
+ | protected Handler successor; | ||
+ | |||
+ | public void SetSuccessor(Handler successor) | ||
+ | { | ||
+ | this.successor = successor; | ||
+ | } | ||
+ | |||
+ | public abstract void HandleRequest(int request); | ||
+ | } | ||
+ | |||
+ | class ConcreteHandler1 : Handler | ||
+ | { | ||
+ | public override void HandleRequest(int request) | ||
+ | { | ||
+ | if (request >= 0 && request < 10) | ||
+ | { | ||
+ | Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); | ||
+ | } | ||
+ | else if (successor != null) | ||
+ | { | ||
+ | successor.HandleRequest(request); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class ConcreteHandler2 : Handler | ||
+ | { | ||
+ | public override void HandleRequest(int request) | ||
+ | { | ||
+ | if (request >= 10 && request < 20) | ||
+ | { | ||
+ | Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); | ||
+ | } | ||
+ | else if (successor != null) | ||
+ | { | ||
+ | successor.HandleRequest(request); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class ConcreteHandler3 : Handler | ||
+ | { | ||
+ | public override void HandleRequest(int request) | ||
+ | { | ||
+ | if (request >= 20 && request < 30) | ||
+ | { | ||
+ | Console.WriteLine("{0} handled request {1}",this.GetType().Name, request); | ||
+ | } | ||
+ | else if (successor != null) | ||
+ | { | ||
+ | successor.HandleRequest(request); | ||
+ | } | ||
+ | } | ||
+ | } | ||
</source> | </source> | ||
Версия 10:54, 1 августа 2014
Другое название
Назначение
Некий запрос должен быть обработан в цепочке взаимосвязанных объектов (список, дерево - движение от листьев к корню). Объект либо обрабатывает запрос, либо передвает по цепочке следующему объекту. Если ни один из объектов не обработал запрос, то может происходить какое-то действие.
Описание
Имеется цепочка объектов, каждый хранит ссылку на следующий объект (как правило, объект более верхнего уровня) Запрос перемещается по цепочке объектов вверх пока один из них не обработает этот запрос. У объекта, отправившего запрос на обработку, отсутствует информация о том, какой объект в цепочке обработает запрос.
Пример: докладная пишется непосредственному начальнику, он либо реагирует на нее, либо передает по иерархии вверх своему непосредственному начальнику и т.д.
Использование
Паттерн Цепочка обязанностей используется если есть более одного объекта, способного обработать запрос, причем, настоящий обработчик неизвестен и должен быть найден автоматически
Реализация
Диаграмма классов
Участники
Пример
class MainApp
{
static void Main()
{
// Setup Chain of Responsibility
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
Handler h3 = new ConcreteHandler3();
h1.SetSuccessor(h2);
h2.SetSuccessor(h3);
// Generate and process request
int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
h1.HandleRequest(2);
h1.HandleRequest(22);
h1.HandleRequest(222);
}
}
abstract class Handler
{
protected Handler successor;
public void SetSuccessor(Handler successor)
{
this.successor = successor;
}
public abstract void HandleRequest(int request);
}
class ConcreteHandler1 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 0 && request < 10)
{
Console.WriteLine("{0} handled request {1}", this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
class ConcreteHandler2 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 10 && request < 20)
{
Console.WriteLine("{0} handled request {1}", this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
class ConcreteHandler3 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 20 && request < 30)
{
Console.WriteLine("{0} handled request {1}",this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}