Chain of responsibility
От: Aviator  
Дата: 03.09.06 19:49
Оценка:
Пристально посмотрев на этот паттерн пришёл к выводу, что в нём чего то не хватает для законченности . Тпичная задача: есть набор компонент (классов), пердоставляющих некоторый набор сервисов. Соединяем всё это добро в оддно связанное приложение, в котором источниками и обработчиками запросов выступает этот набор компонент. И тут натыкаемся на проблему — во первых если один компонент инициирует некоторый запрос, вызывая при этом _nextComponent->Handle(aRequest), обраьотать запрос смогут только нижестоящие в списке компоненты... Далее, нередко требуется что бы обработать запрос мог только один компонент и при этом вернуть инициирующему запрос объекту результат... И на последок — в некоторых случаях компонент должен быть уверен, что созданный им запрос был получен всеми объектами в цепочке... Ну и напоследок — требуется средство формирование очереди, что бы некотрые объекты могли раньше получать сообщения... Вобщем по моему в классическом варианте от GoF много непоняток. Есть идеии как формализовать это всё хозяйство?
Re: Chain of responsibility
От: vse_ravno_ya_budu_anonim  
Дата: 04.09.06 06:11
Оценка:
Здравствуйте, Aviator, Вы писали:

A>Далее, нередко требуется что бы обработать запрос мог только один компонент и при этом вернуть инициирующему запрос объекту результат...


Именно так и происходит. Обрабатывает запрос один компонент и возвращает результат. А если компонент не может обработать запрос, он передает его дальше.

A>И на последок — в некоторых случаях компонент должен быть уверен, что созданный им запрос был получен всеми объектами в цепочке...


Ну это да, об этом и упоминается — "получение не гарантировано".

A>Ну и напоследок — требуется средство формирование очереди, что бы некотрые объекты могли раньше получать сообщения...


Ну это, видимо, будет совсем другой паттерн. Скажи, какие у тебя задачи, постараюсь помочь чем смогу.
Re[2]: Chain of responsibility
От: Аноним  
Дата: 04.09.06 06:27
Оценка:
Здравствуйте, vse_ravno_ya_budu_anonim, Вы писали:

___>Здравствуйте, Aviator, Вы писали:


A>>Далее, нередко требуется что бы обработать запрос мог только один компонент и при этом вернуть инициирующему запрос объекту результат...


___>Именно так и происходит. Обрабатывает запрос один компонент и возвращает результат. А если компонент не может обработать запрос, он передает его дальше.

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

A>>И на последок — в некоторых случаях компонент должен быть уверен, что созданный им запрос был получен всеми объектами в цепочке...


___>Ну это да, об этом и упоминается — "получение не гарантировано".


обработан всеми означает, что каждый ПОЛУЧИТ возможность его обработать, то есть ни у какого компонента не будет возможность прервать цепочку

A>>Ну и напоследок — требуется средство формирование очереди, что бы некотрые объекты могли раньше получать сообщения...


___>Ну это, видимо, будет совсем другой паттерн. Скажи, какие у тебя задачи, постараюсь помочь чем смогу.


почему же другой, не другной а доработанный chain of responsibility .

PS задача простая — хочется собрать набор компонент, на которые разбита исходная задача с минимальной связностью между ними и максимальной расширяемостью.
Re[2]: Chain of responsibility
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 04.09.06 07:45
Оценка: -1
Здравствуйте, vse_ravno_ya_budu_anonim, Вы писали:

___>Именно так и происходит. Обрабатывает запрос один компонент и возвращает результат. А если компонент не может обработать запрос, он передает его дальше.


Все-таки лучше отделить поиск компонента для обработки от самой обработки. Т.е. есть набор объектов-обработчиков, которые могут быть сгруппированы:

а) в массив;
б) в список;
в) в очередь;
г) в стек;
д) в матрицу;
е) в дерево;
ж) в граф;
з) и т.д.

Соответственно, существуют два процесса (две функции):

1) процесс поиска нужного обработчика из набора;
2) процесс обработки (вызова функции обработчика).

Именно таким образом организована обработка сообщений в профессиональных GUI-библиотеках — MFC, OWL.

А Chain of Responsibility — лишь частный случай этого решения. Кстати, в этом и заключается слабость паттернов GoF. Книга представляет собой просто набор частных случаев. Не рассматривается развитие идей решений.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[3]: Chain of responsibility
От: Аноним  
Дата: 04.09.06 08:06
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, vse_ravno_ya_budu_anonim, Вы писали:


___>>Именно так и происходит. Обрабатывает запрос один компонент и возвращает результат. А если компонент не может обработать запрос, он передает его дальше.


КЛ>Все-таки лучше отделить поиск компонента для обработки от самой обработки. Т.е. есть набор объектов-обработчиков, которые могут быть сгруппированы:


важным элементом является тот факт, что задачу определения кому предназнасчен запрос решает сам компонент.
Re[3]: Chain of responsibility
От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
Дата: 04.09.06 08:30
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, vse_ravno_ya_budu_anonim, Вы писали:


___>>Именно так и происходит. Обрабатывает запрос один компонент и возвращает результат. А если компонент не может обработать запрос, он передает его дальше.


КЛ>Все-таки лучше отделить поиск компонента для обработки от самой обработки. Т.е. есть набор объектов-обработчиков, которые могут быть сгруппированы:


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

КЛ>Соответственно, существуют два процесса (две функции):


КЛ>1) процесс поиска нужного обработчика из набора;

КЛ>2) процесс обработки (вызова функции обработчика).

КЛ>Именно таким образом организована обработка сообщений в профессиональных GUI-библиотеках — MFC, OWL.


MFC, к примеру, уже давно лежит в земле.

КЛ>А Chain of Responsibility — лишь частный случай этого решения. Кстати, в этом и заключается слабость паттернов GoF.


Это очень "интересное" мнение я слышу в первый раз. Тема для книги есть — "Слабость паттернов GoF".

КЛ>Книга представляет собой просто набор частных случаев.


Есть ли у Вас более конкретные доводы? Паттерн — это и есть частный случай и они не призваны решать все Ваши проблемы.

КЛ>Не рассматривается развитие идей решений.


Каждый паттерн в книге GoF несет только необходимую информацию, если говорить о развитии идей решений. Все остальное — это комбинирование паттернов.

Касательно вопроса Автора ветки.

  1. "Добавить возможность посылки сообщения не только нижестоящим" — добавьте в интерфейс обработчика не только ссылку на следующий обработчик, но на голову списка.
  2. "в некоторых случаях компонент должен быть уверен, что созданный им запрос был получен всеми объектами в цепочке..." — добавьте в объект запроса логинрование проходящих им обработчиков, то есть пусть каждый обработчик вызывает метод запроса Log и после прохождения цепи спросите у запроса, кто его получил.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Chain of responsibility
От: Аноним  
Дата: 04.09.06 09:31
Оценка:
Здравствуйте, pt4h, Вы писали:


P>
  • "в некоторых случаях компонент должен быть уверен, что созданный им запрос был получен всеми объектами в цепочке..." — добавьте в объект запроса логинрование проходящих им обработчиков, то есть пусть каждый обработчик вызывает метод запроса Log и после прохождения цепи спросите у запроса, кто его получил.
    P>[/list]

    не в этом задача нужно что бы никакой компонент в цепочке для некоторых сообщений не имел возможности прервать обработку, отказавшись вызвать next->Handle(theRequest)
  • Re[5]: Chain of responsibility
    От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
    Дата: 04.09.06 09:56
    Оценка:
    Здравствуйте, <Аноним>, Вы писали:

    А>Здравствуйте, pt4h, Вы писали:



    P>>
  • "в некоторых случаях компонент должен быть уверен, что созданный им запрос был получен всеми объектами в цепочке..." — добавьте в объект запроса логинрование проходящих им обработчиков, то есть пусть каждый обработчик вызывает метод запроса Log и после прохождения цепи спросите у запроса, кто его получил.
    P>>[/list]

    А>не в этом задача нужно что бы никакой компонент в цепочке для некоторых сообщений не имел возможности прервать обработку, отказавшись вызвать next->Handle(theRequest)


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

    Ниже реализация "сходу" для примера:

    public interface IRequestHandler
    {
        object Handle (IRequest request, IChainSurrogate chain);
        
        bool CanHandle (IRequest request);
    }
    
    public interface IChainSurrogate
    {
        void Register(IRequestHandler handler);
        
        void UnRegister(IRequestHandler handler);
        
        object Accept(IRequest request);
    }
    
    public class StrictChainOfResponsibility : IChainSurrogate
    {
        private IList<IRequestHandler> handlers;
        
        public void Register(IRequestHandler handler)
        {
            this.handlers.Add(handler);
        }
        
        public void UnRegister(IRequestHandler handler)
        {
            this.handerls.Remove(handler);
        }
        
        public object Accept(IRequest request)
        {
            // Вот тут мы можем утсанавливать свои правила по обработке
            foreach (IRequestHandler r in this.handlers)
            {
                // Например, все должны его обработать, если могут
                if (r.CanHandle(request))
                {
                    // Вот тут мы можем еще одно событие запостить используя IChainSurrogate интерфейс
                    r.Handle(request, this);
                }
            }
        }
    }


    Повторюсь, этот код уже далеко не "оригинальная" Chain of Responsibility.
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
  • Re[6]: Chain of responsibility
    От: Аноним  
    Дата: 04.09.06 10:19
    Оценка:
    Здравствуйте, pt4h, Вы писали:

    P>Повторюсь, этот код уже далеко не "оригинальная" Chain of Responsibility.


    согласен с реализацией, оригинальные паьттерны в чистом виде я пока на практике не встречал
    Re[4]: Chain of responsibility
    От: Кирилл Лебедев Россия http://askofen.blogspot.com/
    Дата: 04.09.06 11:45
    Оценка:
    Здравствуйте, pt4h, Вы писали:

    КЛ>>Все-таки лучше отделить поиск компонента для обработки от самой обработки. Т.е. есть набор объектов-обработчиков, которые могут быть сгруппированы:


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


    Необязательно. Можно ввести два объекта:

    1) Хранильщик обработчиков.
    2) Поисковик обработчика.

    Хранильщик хранит все обработчики, а поисковик последовательно получает их из хранильщика при помощи специфицированного интерфейса. Что в этом плохого?

    P>MFC, к примеру, уже давно лежит в земле.


    Это никак не свидетельствует о плохом качестве локальных решений.

    P>Это очень "интересное" мнение я слышу в первый раз. Тема для книги есть — "Слабость паттернов GoF".


    Возможно, такая книга выйдет. Но пока что материал существует в виде отдельных статей.

    P>Есть ли у Вас более конкретные доводы? Паттерн — это и есть частный случай и они не призваны решать все Ваши проблемы.


    Свои доводы (относительно Chain Of Responsibility) я привел выше. Могу повторить:

    1) Этот паттерн подразумевает только один способ группировки данных — список.
    2) Сам контейнер (список) не отделен от хранимых в нем данных. А эта особенность характерна только для устаревших языков программирования, например, Си.
    3) Функция поиска (принятия решения) смешена с операцией выполнения принятого решения (обработки команды). Что тоже плохо. Текущая тенденция — разделение этих функций.

    P>Каждый паттерн в книге GoF несет только необходимую информацию, если говорить о развитии идей решений. Все остальное — это комбинирование паттернов.


    Это слишком упрощенное представление.
    С уважением,
    Кирилл Лебедев
    Software Design blog — http://askofen.blogspot.ru/
    Re[4]: Chain of responsibility
    От: Кирилл Лебедев Россия http://askofen.blogspot.com/
    Дата: 04.09.06 11:50
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    А>важным элементом является тот факт, что задачу определения кому предназнасчен запрос решает сам компонент.


    Это плохо. Нужно разделять, а не смешивать ответственность. Можно сделать так:

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

    Т. обр., обработчик заполняет структуру данных (подбирает значения для критериев), а алгоритм поиска — делает выбор.
    С уважением,
    Кирилл Лебедев
    Software Design blog — http://askofen.blogspot.ru/
    Re[5]: Chain of responsibility
    От: Аноним  
    Дата: 04.09.06 11:59
    Оценка:
    Здравствуйте, Кирилл Лебедев, Вы писали:

    КЛ>Здравствуйте, Аноним, Вы писали:


    А>>важным элементом является тот факт, что задачу определения кому предназнасчен запрос решает сам компонент.


    КЛ>Это плохо. Нужно разделять, а не смешивать ответственность. Можно сделать так:


    совершенно не согласен! наоборот логично что каждый компонент сам отвечает что он обрабатывает тем самым мзолирую объединяющее звено от бизнес логики. Таким образом мы достигаем высокой степени гибкости приложения, когда легко добавляются новые компоненты и новые запросы. Если решение кто что обрабатывает принимаепт центральное звено то мы помещаем большую. часть доменной логики в один компонент и тем самым катострофически уменьшаем гибкость и усиливаем связность.
    Re[5]: Chain of responsibility
    От: Аноним  
    Дата: 04.09.06 12:04
    Оценка:
    Здравствуйте, Кирилл Лебедев, Вы писали:

    а теперь в противовес вышесказанному простой пример — есть два комопнента — первый А отсылает RequestA, который ловит второй компонент B. я хочу добавить компонент C, который будет перехватывать запрос RequestA, создавать RequestAB и оьтсылать его на обработку компоненту D, который в свою очередь формирует новый запрос RequestA и пересылает его в некотором виде компоненту B. В архитектуре без центрального звена это делает прозрачно добавлением двух компонент и редактирыванием некого конфигурационного файла, при этом алгоритм может изменится до неузнаваемости. А в вашем варианте придётся править некоторое общее для _всех_ компонент звено, пересобирать систему и получить кучу гемора в поддержке...
    Re[5]: Chain of responsibility
    От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
    Дата: 04.09.06 12:05
    Оценка:
    Здравствуйте, Кирилл Лебедев, Вы писали:

    КЛ>Здравствуйте, Аноним, Вы писали:


    А>>важным элементом является тот факт, что задачу определения кому предназнасчен запрос решает сам компонент.


    КЛ>Это плохо. Нужно разделять, а не смешивать ответственность. Можно сделать так:


    КЛ>1) Алгоритм поиска подходящего обработчика предоставляет структуру данных (набор критериев), которая заполняется обработчиком.

    КЛ>2) На основе заполненной структуры данных алгоритм поиска обработчика принимает решение (делает выбор).

    КЛ>Т. обр., обработчик заполняет структуру данных (подбирает значения для критериев), а алгоритм поиска — делает выбор.


    В этом решении есть несколько проблем:
    1. Если набор данных, которые необходимо заполнять изменяется, изменения придется вносить во все обработчики.
    2. Так как мы не привязываемся к обработчику, то каждый из них может быт исключительно уникальным и соответственно данные и критерии могут быть абсолютно разными. В итоге эта структура соберет в себя все возможные критерии.
    3. Если критерии не могу быть представлены в виде выделнных данных, а являются скажем результатом выполнения какого-то алгоритма в момент обработки данных — поиск по критерию тоже не будет работать.
    4. Количество структур поиска будет расти вместе с количеством событий.

    Все эти проблемы будут неизбежно вести к изменениям в структуре поиска и обработчиках, что не хорошо в нашем случае, так как мы стараемся не привязываться к обработчику.
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    Re[5]: Chain of responsibility
    От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
    Дата: 04.09.06 12:16
    Оценка:
    Здравствуйте, Кирилл Лебедев, Вы писали:

    КЛ>Здравствуйте, pt4h, Вы писали:


    КЛ>>>Все-таки лучше отделить поиск компонента для обработки от самой обработки. Т.е. есть набор объектов-обработчиков, которые могут быть сгруппированы:


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


    КЛ>Необязательно. Можно ввести два объекта:


    КЛ>1) Хранильщик обработчиков.

    КЛ>2) Поисковик обработчика.

    КЛ>Хранильщик хранит все обработчики, а поисковик последовательно получает их из хранильщика при помощи специфицированного интерфейса. Что в этом плохого?


    К этому вопросу в посте
    Автор: pt4h
    Дата: 04.09.06
    выше по ветке.

    КЛ>Свои доводы (относительно Chain Of Responsibility) я привел выше. Могу повторить:


    КЛ>1) Этот паттерн подразумевает только один способ группировки данных — список.


    Он не определяет никаких способов группировки Можно построить дерево и обходить его.

    КЛ>2) Сам контейнер (список) не отделен от хранимых в нем данных. А эта особенность характерна только для устаревших языков программирования, например, Си.


    Учитывая пункт 1 нет ничего плохо в том, что мы храним ссылки на "элементы". Если мы выбираем контейнер, мы подвергаем ограничениям способ выбора следующего обработчика. Пол цепи может быть списком, пол деревом

    КЛ>3) Функция поиска (принятия решения) смешена с операцией выполнения принятого решения (обработки команды). Что тоже плохо. Текущая тенденция — разделение этих функций.


    Разделение в данном случае приведет к 2N классам вместо N и разбрасываение обязанностей приведет к сложному сопровождению и пониманию.

    P>>Каждый паттерн в книге GoF несет только необходимую информацию, если говорить о развитии идей решений. Все остальное — это комбинирование паттернов.


    КЛ>Это слишком упрощенное представление.


    Паттерны — это строительные кирпичики. Кирпич не лолжен сразу же содержать встроенную розетку
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    Re[6]: Chain of responsibility
    От: Кирилл Лебедев Россия http://askofen.blogspot.com/
    Дата: 04.09.06 13:41
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    А>а теперь в противовес вышесказанному простой пример — есть два комопнента — первый А отсылает RequestA, который ловит второй компонент B. я хочу добавить компонент C, который будет перехватывать запрос RequestA, создавать RequestAB и оьтсылать его на обработку компоненту D, который в свою очередь формирует новый запрос RequestA и пересылает его в некотором виде компоненту B. В архитектуре без центрального звена это делает прозрачно добавлением двух компонент и редактирыванием некого конфигурационного файла, при этом алгоритм может изменится до неузнаваемости. А в вашем варианте придётся править некоторое общее для _всех_ компонент звено, пересобирать систему и получить кучу гемора в поддержке...


    В Вашем сообщении содержатся 2 утверждения:

    1) Архитектура, предложенная мной, потребует изменений во всех звеньях при добавлении компонентов C и D.
    2) Chain of Responsibility (в классическом виде) будет легче поддержать.

    Оба утверждения не соответствуют истине. Постараюсь это показать.

    Относительно 1.

    Есть 2 объекта:

    1) Хранитель обработчиков, который хранит объекты, как удобнее (в виде очереди, списка, массива, дерева и т.п.).
    2) Поисковик подходящего объекта, который ищет по заданному алгоритму (первый подходящий, последний подходящий или какому -либо другому правилу) в Хранителе.

    Сначала в Хранителе объектов 2 объекта: A и B. При необходимости, добавляем еще два — C и D. Помещаем их в нужное место (это можно сделать тоже при помощи конфигурационного файла), и вуаля! Где же проблема, о которой пишите Вы? Дополнительные объекты добавлять так же просто.

    Относительно 2.

    А теперь мысленно представьте, что объектов типа C и D у Вас не 2, а десяток, сотня, тысяча. Каждый из них перехватывает какое-нибудь сообщение, преобразует в другое и отсылает другому объекту, который его преобразует и отсылает еще какому-нибудь объекту. Вам будет удобно сопровождать такую систему? Думаю, что очень быстро Вы запутаетесь и перестанете понимать, какое действие следует за каким действием.

    Chain of Responsibility имеет существенные ограничения на длину цепочки.
    С уважением,
    Кирилл Лебедев
    Software Design blog — http://askofen.blogspot.ru/
    Re: Chain of responsibility
    От: konsoletyper Россия https://github.com/konsoletyper
    Дата: 04.09.06 15:27
    Оценка:
    Здравствуйте, Aviator, Вы писали:

    A>Пристально посмотрев на этот паттерн пришёл к выводу, что в нём чего то не хватает для законченности . Тпичная задача: есть набор компонент (классов), пердоставляющих некоторый набор сервисов. Соединяем всё это добро в оддно связанное приложение, в котором источниками и обработчиками запросов выступает этот набор компонент. И тут натыкаемся на проблему — во первых если один компонент инициирует некоторый запрос, вызывая при этом _nextComponent->Handle(aRequest), обраьотать запрос смогут только нижестоящие в списке компоненты... Далее, нередко требуется что бы обработать запрос мог только один компонент и при этом вернуть инициирующему запрос объекту результат... И на последок — в некоторых случаях компонент должен быть уверен, что созданный им запрос был получен всеми объектами в цепочке... Ну и напоследок — требуется средство формирование очереди, что бы некотрые объекты могли раньше получать сообщения... Вобщем по моему в классическом варианте от GoF много непоняток. Есть идеии как формализовать это всё хозяйство?


    Может, Mediator + Observer? Кстати, я даже Mediator + Observer + Chain of responsibility. Это дело умещается в библиотеке легковесных контролов. Все контролы располагаются не хосте, который в плане отрисовки и кэширования layout-а является медиатором. Контролы, принимающие ввод реализуют Observer (в дотнете он реализован на уровне языка). Ну а обработка клавиатуры производится при помощи Chain of responsibility — если контрол отказывается обрабатывать клавишу, то она перенаправляется его контейнеру. ИМХО, нужно уметь использовать простые паттерны в композиции, а не придумывать какие-то супер-мега-сложные паттерны.
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    Re[7]: Chain of responsibility
    От: Аноним  
    Дата: 05.09.06 05:03
    Оценка: +1
    Здравствуйте, Кирилл Лебедев, Вы писали:


    КЛ>Оба утверждения не соответствуют истине. Постараюсь это показать.


    КЛ>Относительно 1.


    КЛ>Есть 2 объекта:


    КЛ>1) Хранитель обработчиков, который хранит объекты, как удобнее (в виде очереди, списка, массива, дерева и т.п.).

    КЛ>2) Поисковик подходящего объекта, который ищет по заданному алгоритму (первый подходящий, последний подходящий или какому -либо другому правилу) в Хранителе.

    как поисковик узнаёт что объект подходит для обработки сообщения? приведите пример реализации и вы увидите что вощникнет проблема...


    КЛ>Относительно 2.


    КЛ>А теперь мысленно представьте, что объектов типа C и D у Вас не 2, а десяток, сотня, тысяча. Каждый из них перехватывает какое-нибудь сообщение, преобразует в другое и отсылает другому объекту, который его преобразует и отсылает еще какому-нибудь объекту. Вам будет удобно сопровождать такую систему? Думаю, что очень быстро Вы запутаетесь и перестанете понимать, какое действие следует за каким действием.


    КЛ>Chain of Responsibility имеет существенные ограничения на длину цепочки.

    а если у вас будет здоровый класс, содержащий тысячи строк логики корму в каких случаях и когда что отсылать не запутаетесь ли вы что к чему и как поддерживать? Про ограничение на долину цепочки не согласен, не вижу серьёзной аргументации, разве что группировать наверно лучше в некоторую иерархическую структуру. Посмотрите архитектуру драйверов в windows — там как раз цепочка фильтров обработчиков... может не самый хороший пример но всё же.
    Re[8]: Chain of responsibility
    От: Кирилл Лебедев Россия http://askofen.blogspot.com/
    Дата: 05.09.06 08:11
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    А>как поисковик узнаёт что объект подходит для обработки сообщения? приведите пример реализации и вы увидите что вощникнет проблема...


    Приведите Ваш пример, и я распишу, как это можно сделать... Если говорить о других примерах, то, например, в OWL поиск обработчика осуществляется таким образом:

    1. Сначала обработчик ищется в обработчиках контрола, который инициировал сообщение. Это на тот случай, когда программист хочет, чтобы кнопка САМА обрабатывала свое нажатие.
    2. Затем обработчик ищется в обработчиках окна, которому пришло сообщение. (Команды от контрола приходят родительскому окну.)
    3. Затем обработчик ищется в обработчиках родителя родителя и т.д.
    4. И, наконец, обработчик ищется в объекте приложения.

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

    1) Ищем обработчик в таблице финального класса.
    2) Если не нашли, то ищем обработчик в таблицах базовых классов.
    3) И т.д. рекурсивно.

    Для поиска обработчика в таблицах используются 3 критерия:

    1) Идентификатор сообщения.
    2) Идентификатор команды, если сообщение WM_COMMAND или WM_NOTIFY.
    3) Идентификатор контрола, пославшего WM_COMMAND или WM_NOTIFY.

    Заметьте, в этой схеме реализована классическая Chain of Responsibility. Тем не менее, можно выделить критерии поиска:

    1. Место нахождения обработчика.
    2. Идентификатор сообщения, которое обрабатывает обработчик.
    3. Идентификаторы отправителя и/или предполагаемого получателя сообщения (откуда начинаем поиск).
    4. Дополнительные данные для обработки специализированных сообщений типа WM_COMMAND, WM_NOTIFY.

    Разумеется, для другого примера можно построить свой механизм.

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


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

    А>Про ограничение на долину цепочки не согласен, не вижу серьёзной аргументации, разве что группировать наверно лучше в некоторую иерархическую структуру. Посмотрите архитектуру драйверов в windows — там как раз цепочка фильтров обработчиков... может не самый хороший пример но всё же.


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

    Можно хранить десяток и даже сотню объектов в массиве. Но для реализации реляционной базы данных, в которой содержатся миллионы записей, массив явно не подходит.
    С уважением,
    Кирилл Лебедев
    Software Design blog — http://askofen.blogspot.ru/
    Re[9]: Chain of responsibility
    От: Аноним  
    Дата: 05.09.06 08:30
    Оценка:
    Здравствуйте, Кирилл Лебедев, Вы писали:

    КЛ>Здравствуйте, Аноним, Вы писали:


    А>>как поисковик узнаёт что объект подходит для обработки сообщения? приведите пример реализации и вы увидите что вощникнет проблема...


    КЛ>Приведите Ваш пример, и я распишу, как это можно сделать... Если говорить о других примерах, то, например, в OWL поиск обработчика осуществляется таким образом:


    КЛ>1. Сначала обработчик ищется в обработчиках контрола, который инициировал сообщение. Это на тот случай, когда программист хочет, чтобы кнопка САМА обрабатывала свое нажатие.

    КЛ>2. Затем обработчик ищется в обработчиках окна, которому пришло сообщение. (Команды от контрола приходят родительскому окну.)
    КЛ>3. Затем обработчик ищется в обработчиках родителя родителя и т.д.
    КЛ>4. И, наконец, обработчик ищется в объекте приложения.

    КЛ>Каждый объект, упомянутый в этом алгоритме, может быть объектом класса, который выведен из других классов. Соответственно, при поиске обработчика внутри объекта выполняется такой алгоритм:


    КЛ>1) Ищем обработчик в таблице финального класса.

    КЛ>2) Если не нашли, то ищем обработчик в таблицах базовых классов.
    КЛ>3) И т.д. рекурсивно.

    КЛ>Для поиска обработчика в таблицах используются 3 критерия:


    КЛ>1) Идентификатор сообщения.

    КЛ>2) Идентификатор команды, если сообщение WM_COMMAND или WM_NOTIFY.
    КЛ>3) Идентификатор контрола, пославшего WM_COMMAND или WM_NOTIFY.

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

    КЛ>Разумеется, для другого примера можно построить свой механизм.


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


    КЛ>Наличие такого класса (который содержит "тысячи строк логики") свидетельствует о том, что класс спроектирован неверно. Скорее всего, этот класс выполняет кучу функций разного уровня сложности (да и вообще просто разных функций). Это уже, извините, помойка получается, а не класс.


    имеенно это вы и имеете в вашем лбимом MFC в виде карты сообщений... ужасный свитч по идетификаторам сообщений.
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.