Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Design Patterns via C#.pdf
Скачиваний:
154
Добавлен:
17.03.2016
Размер:
13.25 Mб
Скачать

166

Паттерн Chain of Responsibility

Название

Цепочка обязанностей

Также известен как

-

Классификация

По цели: поведенческий По применимости: к объектам

Частота использования

Ниже средней - 1 2 3 4 5

Назначение

Паттерн Chain of Responsibility - позволяет избежать привязки объекта-отправителя запроса к объекту-получателю запроса, при этом давая шанс обработать этот запрос нескольким объектам. Паттерн Chain of Responsibility – связывает в цепочку объекты-получатели запроса и передает запрос вдоль этой цепочки, пока один из объектов, составляющих эту цепочку не обработает передаваемый запрос.

Введение

В реальной жизни, сложно найти рациональный аналог модели, которую описывает паттерн Chain of Responsibility. Для лучшего понимания работы паттерна можно привести нереалистичный пример. Например, предлагается рассмотреть работу бюро переводов с английского языка на другие иностранные языки. Имеется три переводчика англо-немецкий, англо-китайский и англо-русский. Переводчики сидят за столами один за другим. Когда клиент приходит в бюро то он имеет дело только с одним переводчиком, который сидит за первым столом (англо-немецким). Клиент дает англо-немецкому переводчику документ для перевода на определенный язык. Англо-немецкий (первый в цепочке) переводчик определяет язык перевода, и если он в состоянии сделать перевод, то он переводит документ, если не в состоянии, то передает документ дальше по цепочке (сидящему у него за спиной) англо-китайскому переводчику и так далее.

Ниже на рисунке показано, что клиенту требуется сделать перевод документа с китайского языка на английский. Клиент дает документ на китайском языке англо-немецкому переводчику. Англо-немецкий переводчик понимает, что не в состоянии сделать перевод и передает документ дальше по цепочке, следующему переводчику. Следующим переводчиком оказывается англо-китайский переводчик, который в состоянии сделать перевод. Англо-китайский переводчик делает перевод документа на английский язык и возвращает документ клиенту. Англо-русский переводчик остался не задействованным в данном случае.

NO YES

167

Если ни один из переводчиков не может перевести документ, то документ теряется. Ниже на рисунке показано, что клиенту требуется сделать перевод документа с японского языка на английский. Клиент дает документ на японском языке англо-немецкому переводчику. Англо-немецкий переводчик понимает, что не в состоянии сделать перевод и передает документ дальше по цепочке, следующему переводчику. Следующим переводчиком оказывается англо-китайский переводчик. Англо-китайский переводчик понимает, что не в состоянии сделать перевод и передает документ дальше по цепочке, следующему переводчику. Следующим переводчиком оказывается англо-русский переводчик. Англорусский переводчик понимает, что не в состоянии сделать перевод и так как за ним уже нет больше переводчиков то просто выбрасывает документ в корзину с мусором (условно).

NO

NO

NO

Положительные стороны такого подхода заключаются в том, что клиент не знает о том переводчике который делает перевод, при этом каждый из переводчиков знает только об одном переводчике (который у него за спиной), что обеспечивает слабую связанность всей системы. Недостаток подхода в том, что нет никаких гарантий что перевод будет выполнен, так как документ может достичь конца цепочки и пропасть.

Структура паттерна на языке UML

См. Пример к главе: \013_Chain of Responsibility\001_Chain

168

Структура паттерна на языке C#

class Program { static void Main() { Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2();

h1.Successor = h2; h1.HandleRequest(1); h1.HandleRequest(2); } }

abstract class Handler

 

 

{

 

 

public Handler Successor

{ get; set;

}

public abstract void HandleRequest(int request);

}

 

 

class ConcreteHandler1 : Handler

class ConcreteHandler2 : Handler

{

{

public override void HandleRequest(int request)

public override void HandleRequest(int request)

{

{

if (request == 1)

if (request == 2)

Console.WriteLine("One");

Console.WriteLine("Two");

else if (Successor != null)

else if (Successor != null)

Successor.HandleRequest(request);

Successor.HandleRequest(request);

}

}

}

}

Структура объектов:

См. Пример к главе: \013_Chain of Responsibility\001_Chain

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]