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

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Описание)
(Пример)
Строка 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

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

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

Назначение

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

Описание

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

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

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

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

Реализация

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

Файл:Common.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);
        }
    }
}

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

Варианты