Схема цепочки ответственности - PullRequest
3 голосов
/ 08 февраля 2012

Может ли кто-нибудь дать простое объяснение модели цепочки ответственности? Я нашел статью в вики немного запутанной.

Ответы [ 6 ]

7 голосов
/ 08 февраля 2012

Очень хорошим примером являются фильтры сервлетов Java - фрагменты кода, которые выполняются до того, как HTTP-запрос достигает своей цели.

  • цепочка содержит несколько экземпляров, и каждыйиз них выполняет различное действие
  • каждый экземпляр в цепочке может выбрать распространение на следующий экземпляр или остановку потока

Таким образом, с фильтрами сервлетов вы можете иметь

  • фильтр, который проверяет, аутентифицирован ли пользователь.Если он есть, фильтр распространяется на следующий фильтр

  • , следующий фильтр проверяет, есть ли у пользователя разрешения на текущий ресурс.Если это так, он распространяется на следующую

  • следующую запись в журнал текущего URL-адреса запроса и имени пользователя и всегда распространяется на следующую

  • в цепочке больше ничего нет, поэтому целевой объект наконец вызывается

4 голосов
/ 08 февраля 2012

Попробую по аналогии:

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

Теперь вы бросаете шайбу сверху. Если радиус шайбы больше первого отверстия, он застрянет в ней и не упадет ниже. Значение команды было обработано первым обработчиком.

Но если шайба меньше, чем дыра, она будет проходить через нее до следующей и так далее, пока не попадет или не провалится через все сети. Все сети (классы обработчиков ответственности), через которые проходит шайба, обработали шайбу (обработали команду).

2 голосов
/ 08 февраля 2012

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

Преимущества

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

1017 * Недостатки * выполнение запроса не гарантируется, оно может выпасть из цепочки, если ни один объект не обработает его характеристики времени выполнения могут быть трудны для наблюдения и отладки Возможные варианты использования

  • щелчки мыши и события клавиатуры.
  • по электронной почте. Например, электронная почта получена и передана первому обработчику, обработчику спама. Затем он либо обрабатывается, либо передается второму обработчику и т. Д.

От:

Head First Design Patterns


Вот интересная InformIT статья по этому шаблону с примером кода.

1 голос
/ 16 октября 2016

Пост защищен, но я хочу дать ответ, потому что думаю, что он может быть улучшен.

Цепочка ответственности и фильтры.Это одно и то же?

Шаблон фильтра находится рядом с шаблоном цепочки ответственности.
Но этого достаточно, чтобы не смешивать их.
Было бы жаль использовать один и тот же термин для выражения двух разных концепций.

В шаблоне фильтра / перехватчика у нас нет понятия ответственности, посколькунесколько узлов цепочки могут воздействовать на один и тот же поток, и в соответствии с шаблоном он был создан для нескольких обработок.Узлы цепочки не обрабатывают запрос, они участвуют в обработке запроса.
Таким образом, фильтр или перехватчик - это скорее цепочка обработки, чем цепочка ответственности.
Например, АОПработает как фильтры и перехватчики.Мы хотим повторить некоторую обработку из стека процессоров.
Это не вопрос ответственности, а вопрос многоуровневой обработки, которую мы применяем согласно некоторым условиям или нет.Это имеет важные последствия для реализации и логики, лежащей в ее основе.
Фильтры / перехватчики, хранящиеся в цепочке, могут иметь (и часто не имеют) логическую или функциональную связь между ними, в то время как узлы цепочки ответственности всегда имеют логику или функционалотношения между ними, так как они должны решать ту же проблему.Например, в цепочечном фильтре первый фильтр может обрабатывать проблему журналирования, второй фильтр, проблему безопасности и последнюю, проблему кодирования ...
В цепочке ответственности эта же проблема обрабатывается всеми узламицепочка.

Ссылка GOF Цепочка ответственности Намерение:

Избегайте привязки отправителя запроса к его получателю, давая возможность обрабатывать более чем одному объектузапрос.Цепочка получения объектов и передачи запроса по цепочке, пока объект не обрабатывает его.В схеме цепочки ответственности цепочка останавливается, когда узел цепочки обрабатывает это.


Теперь я кратко опишу, что это такое и при использовании его на простом и конкретном примере.

Что такое цепь ответственности?

Шаблон проектирования цепи ответственности является поведенческим шаблоном.Как и все шаблоны проектирования GOF, его имя подходит ему идеально, поскольку шаблон определяет запрос для обработки, цепочку объектов, которые по очереди могут остановить обработку цепочки и ответить на запрос.Этот шаблон предлагает в качестве преимущества для разделения компонентов цепи.Таким образом, мы можем обновлять компоненты независимо и динамически создавать цепочку.

При использовании цепочки ответственности?

В цепочке ответственности только один объект может занятьответственность ответить на запрос.Если мы хотим, чтобы более чем один кандидат мог действовать по запросу, мы избегаем цепочки ответственности.Мы находимся в цепочке обработки.Шаблон фильтра предназначен для такого рода потребностей.

Шаблон цепочки ответственности применяется в нескольких контекстах: как технический, так и бизнес.

Обработка внутренних и пользовательских событий в пользовательских интерфейсах часто описывается.В этом контексте цепочка позволяет графическим слоям и компонентам обрабатывать вводимые пользователем данные, такие как щелчки мыши, нажатые клавиши и т. Д., А также внутреннюю обработку, такую ​​как обработка графического обновления.

Пример с цепочкой ответственности

Мы рассмотрим пример нажатия универсальной кнопки, чтобы проиллюстрировать это.
Кнопка "«универсальный», поскольку его поведение зависит от контекста.

Идея состоит в том, что графические компоненты сортируются в цепочке от более локального компонента, связанного с действием пользователя, к менее локальному компоненту, связанному с действием пользователя.
Как только компонент цепочки решает обработать запрос, поток цепочки останавливается.

ОнВот пример, иллюстрирующий это.
Представьте себе кнопку «сохранить» в строке меню приложения для работы с электронными таблицами.
Сохранение документа, содержащего 2 электронные таблицы, не должно выполняться первой или второй электронной таблицей, поскольку они не должныбыть непосредственно связанными между ними.
Предположим, что при нажатии кнопки "Сохранить" представление отображается во второй электронной таблице.Таким образом, цепочка выполняется путем запуска вторым компонентом электронной таблицы, поскольку он является более локальным компонентом, связанным с действием.Второй компонент электронной таблицы не считает ответственным обрабатывать запрос, поэтому он позволяет обрабатывать его компоненту более высокого уровня, например, компоненту приложения.Когда он получает запрос, компонент приложения имеет всю необходимую информацию для обработки запроса на сохранение, поэтому он выполняет его.
Наоборот, в случаях, когда в документе имеется только одна электронная таблица, мы можем представить, что действие можетвыполняется компонентом электронной таблицы, который самодостаточен.

0 голосов
/ 15 февраля 2019

Пример реализации схемы цепочки ответственности с лямбда-функциями можно найти здесь Цепочка ответственности - лямбда-функции .

Он охватывает функциональность обработки заявки на покупку через различных участников - менеджера, директора, президента, продавца.

0 голосов
/ 18 декабря 2016

Лучший способ понять это - проанализировать простой пример.Вот он:

Программа переводит слово с английского на другие языки (очень упрощенная версия :)) Переведенное слово передается в последующие словари;словари образуют цепочку.

using System;

// The 'Handler' abstract class
abstract class Handler
{
    //chain link
    private Handler _successor;
    //
    static private Handler _first;

    public Handler Successor
    {
        set 
        {
            _successor = value;
        }
        get 
        {
            return _successor;
        }
    }
    public Handler First
    {
        set 
        {
            _first = value;
        }
        get 
        {
           return  _first;
        }
    }
    //
    public void HandleRequest(string request)
    {
        if (First == this)
        {
            Console.WriteLine("\n\tWe translate word => \"{0}\"\n", request);
            First.Translator(request);
        }
        //
        if (Successor != null)
        {
            //Translation by the successor's dictionary 
            Successor.Translator(request);

            //Transfer of word (request) to another chain (dictionary) 
            Successor.HandleRequest(request);
        }
    }
    //
    abstract public void Translator(string word);
}

//The concrete class
class GermanDictionary : Handler
{
    override public void Translator(string word)
    {
        switch (word)
        {
            case "Job":
                word = "Arbeit";
                break;
            case "Rest":
                word = "Rest";
                break;
        }
        Console.WriteLine("\t\tinto German => \"{0}\"", word);
    }
}

class FrenchDictionary : Handler
{
    override public void Translator(string word)
    {
        switch (word)
        {
            case "Job":
                word = "Travail";
                break;
            case "Rest":
                word = "Reste";
                break;
        }
        Console.WriteLine("\t\tinto French => \"{0}\"", word);
    }
}

class PolishDictionary : Handler
{
    override public void Translator(string word) 
    {
        switch (word)
        {
            case "Job":
                word = "Praca";
                break;
            case "Rest":
                word = "Odpoczynek";
                break;
        }
        Console.WriteLine("\t\tinto Polish => \"{0}\"", word);
    }
}
////
class Client
{
    static void Main()
    {
        Handler h1 = new FrenchDictionary();
        Handler h2 = new GermanDictionary();
        Handler h3 = new PolishDictionary();

        //Determining the consequences in the chain
        h1.First=h1;
        h1.Successor=h2;
        h2.Successor=h3;
        h3.Successor=null;

        //The word that is translated
        string request = "Job";

        //Starting the recursive method.
        h1.HandleRequest(request) ;

        //Another word is translated.
        request = "Rest";
        h1.HandleRequest(request);

        Console.ReadKey();
    }
}

/*output:

 We translate word => "Job"

    into French => "Travail"
    into German => "Arbeit"
    into Polish => "Praca"

 We translate word => "Rest"

    into French => "Reste"
    into German => "Rest"
    into Polish => "Odpoczynek"
 */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...