Цепочка обязанностей (Chain of Responsibility) — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Достоинства и недостатки)
(Описание)
Строка 7: Строка 7:
 
=== Описание ===
 
=== Описание ===
 
Имеется цепочка объектов, каждый хранит ссылку на следующий объект (как правило, объект более верхнего уровня)
 
Имеется цепочка объектов, каждый хранит ссылку на следующий объект (как правило, объект более верхнего уровня)
Запрос перемещается по цепочке объектов вверх пока один из них не обработает этот запрос.
+
Запрос перемещается по цепочке объектов вверх пока один из них не обработает (Handle) этот запрос.
 
У объекта, отправившего запрос на обработку, отсутствует информация о том, какой объект в цепочке обработает запрос.
 
У объекта, отправившего запрос на обработку, отсутствует информация о том, какой объект в цепочке обработает запрос.
  
 
Пример: докладная пишется непосредственному начальнику, он либо реагирует на нее, либо передает по иерархии вверх своему непосредственному начальнику и т.д.
 
Пример: докладная пишется непосредственному начальнику, он либо реагирует на нее, либо передает по иерархии вверх своему непосредственному начальнику и т.д.
 +
 +
Данный паттерн повсеместно используется в системах, реализующих графический интерфейс пользователя: нажатие на кнопку может быть обработано самой кнопкой, а может быть передано выше - компоненту, который владеет кнопкой (например, форме).
  
 
=== Использование ===
 
=== Использование ===

Версия 12:00, 1 августа 2014

К основной странице курса

Другое название

Назначение

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

Описание

Имеется цепочка объектов, каждый хранит ссылку на следующий объект (как правило, объект более верхнего уровня) Запрос перемещается по цепочке объектов вверх пока один из них не обработает (Handle) этот запрос. У объекта, отправившего запрос на обработку, отсутствует информация о том, какой объект в цепочке обработает запрос.

Пример: докладная пишется непосредственному начальнику, он либо реагирует на нее, либо передает по иерархии вверх своему непосредственному начальнику и т.д.

Данный паттерн повсеместно используется в системах, реализующих графический интерфейс пользователя: нажатие на кнопку может быть обработано самой кнопкой, а может быть передано выше - компоненту, который владеет кнопкой (например, форме).

Использование

Паттерн Цепочка обязанностей используется если есть более одного объекта, способного обработать запрос, причем, настоящий обработчик неизвестен и должен быть найден автоматически

Реализация

Диаграмма классов

ChainCommon.png

Участники

Пример

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);
        }
    }
}

Достоинства и недостатки

  • Паттерн Цепочка обязанностей освобождает объект от ответственности знать, кто обработает его запрос
  • Объекты, обрабатывающие запрос, можно включать в цепочку динамически
  • Недостаток: нет гарантий, что запрос вообще будет обработан

Варианты