CodeLAB
на главную карта сайта обратная связь
каталог | задачи | паттерны | исходники | стат | форумы | ссылки
 гость
искать в
Главная >> Каталог задач >> Паттерны >> Поведения >> Посредник (Mediator)

<< назад
распечатать обсудить >>


Посредник (Mediator)
реализации: java, количество: 6

Aвтор: this
Дата: 05.10.2007
Просмотров: 116292
Рейтинг: 0/0,0(0)
+
реализации(исходники) +добавить

Имя

«Паттерн
Mediator» оригинал источник codelab.ru codelab.ru

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

Условия, Задача, Назначение

Определяет объект, инкапсулирующий способ взаимодействия множества объектов. источник оригинал codelab.ru codelab.ru
Принимает запросы между независимыми, несвязанными объектами и реализует заданную логику взаимодействия всех этих классов, которые по-прежнему остаются ничего не знающими обо всех других участниках процесса.

Посредник обеспечивает слабую связанность системы, избавляя объекты от необходимости явно ссылаться друг на друга, и позволяя тем самым независимо изменять взаимодействия между ними. codelab.ru codelab.ru оригинал источник

Мотивация

Объектно-ориентированное проектирование способствует распределению некоторого поведения между объектами. Но при этом в получившейся структуре объектов может возникнуть много связей или (в худшем случае) каждому объекту придется иметь информацию обо всех остальных (ссылки на всех остальных). codelab.ru источник codelab.ru оригинал
Несмотря на то что разбиение системы на множество объектов в общем случае повышает степень повторного использования, однако изобилие взаимосвязей приводит к обратному эффекту. Если взаимосвязей слишком много, тогда система подобна монолиту и маловероятно, что объект сможет работать без поддержки других объектов. Более того, существенно изменить поведение системы практически невозможно, поскольку оно распределено между многими объектами. Если вы предпримете подобную попытку, то для настройки поведения системы вам придется определять множество подклассов, чтобы ввести хотя бы одну новую функциональность. источник codelab.ru codelab.ru оригинал
Рассмотрим реализацию диалоговых окон в графическом интерфейсе пользователя. Здесь располагается ряд виджетов: кнопки, меню, поля ввода и т.д. codelab.ru codelab.ru оригинал источник

источник оригинал codelab.ru codelab.ru

Часто между разными виджетами в диалоговом окне существуют зависимости. Например, если одно из полей ввода пустое, то определенная кнопка недоступна. При выборе из списка может измениться содержимое поля ввода. И наоборот, ввод текста в некоторое поле может автоматически привести к выбору одного или нескольких элементов списка. Если в поле ввода присутствует какой-то текст, то могут быть активизированы кнопки, позволяющие произвести определенное действие над этим текстом, например, изменить либо удалить его. codelab.ru оригинал codelab.ru источник
В разных диалоговых окнах зависимости между виджетами могут быть различными. Поэтому, несмотря на то, что во всех окнах встречаются однотипные виджеты, просто взять и повторно использовать готовые классы виджетов не удастся, придется производить настройку с целью учета зависимостей. Индивидуальная настройка каждого виджета – утомительное занятие, ибо участвующих классов слишком много. оригинал источник codelab.ru codelab.ru
Всех этих проблем можно избежать, если инкапсулировать коллективное взаимодействие в отдельном объекте-посреднике. Посредник отвечает за координацию взаимодействий между группой объектов. Он избавляет входящие в группу объекты от необходимости явно ссылаться друг на друга. Все объекты располагают информацией только о посреднике, поэтому количество взаимосвязей сокращается. оригинал codelab.ru источник codelab.ru

оригинал codelab.ru источник codelab.ru

Так, класс FontDialogDirector может служить посредником между виджетами в диалоговом окне. Объект этого класса «знает» обо всех виджетах в окне и координирует взаимодействие между ними, то есть выполняет функции центра коммуникаций. codelab.ru codelab.ru источник оригинал
На следующей диаграмме взаимодействий показано, как объекты кооперируются друг с другом, реагируя на изменение выбранного элемента списка. оригинал источник codelab.ru codelab.ru

codelab.ru источник codelab.ru оригинал

Последовательность событий, в результате которых информация о выбранном элемента списка передается в поле ввода, следующая: codelab.ru codelab.ru оригинал источник
  1. Список информирует распорядителя о происшедших в нем изменениях. codelab.ru источник оригинал codelab.ru
  2. Распорядитель получает от списка выбранный элемент. источник codelab.ru оригинал codelab.ru
  3. Распорядитель передает выбранный элемент полю ввода. codelab.ru источник codelab.ru оригинал
  4. Теперь, когда поле ввода содержит какую-то информацию, распорядитель активизирует кнопки, позволяющие выполнить определенное действие (например, изменить шрифт на полужирный или курсив). источник codelab.ru codelab.ru оригинал
Обратите внимание на то, как распорядитель осуществляет посредничество между списком и полем ввода. Виджеты общаются друг с другом не напрямую, а через распорядитель. Им вообще не нужно владеть информацией друг о друге, они осведомлены лишь о существовании распорядителя (хранят ссылку только на объект распорядителя). А коль скоро поведение локализовано в одном классе, то его несложно модифицировать или сделать совершенно другим путем расширения или замены этого класса. codelab.ru codelab.ru оригинал источник
Можно было вообще выделить отдельную абстракцию FontDialogDirector и интегрировать ее далее в библиотеку классов диалога: источник оригинал codelab.ru codelab.ru

оригинал codelab.ru codelab.ru источник

DialogDirector - это абстрактный класс, который определяет поведение диалогового окна в целом. Клиенты вызывают его операцию ShowDialog для отображения окна на экране. CreateWidgets - это абстрактная операция для создания виджетов в диалоговом окне. WidgetChanged - еще одна абстрактная операция, с ее помощью виджеты сообщают распорядителю об изменениях. Подклассы DialogDirector замещают операции CreateWidgets (для создания нужных виджетов) и WidgetChanged (для обработки извещений об изменениях). источник codelab.ru оригинал codelab.ru

Признаки применения, использования паттерна Посредник (Mediator)

Используйте паттерн посредник, когда: источник codelab.ru оригинал codelab.ru
  1. Имеются объекты, связи между которыми сложны и четко определены.
    Получающиеся при этом взаимозависимости не структурированы и трудны для понимания. codelab.ru оригинал источник codelab.ru
  2. Нельзя повторно и независимо использовать объект (для решения тех же задач, но в другом контексте, например), поскольку он обменивается информацией со многими другими объектами. codelab.ru оригинал codelab.ru источник
  3. Поведение, распределенное между несколькими классами, должно поддаваться настройке без порождения множества подклассов. codelab.ru оригинал источник codelab.ru

Решение

оригинал codelab.ru codelab.ru источник

codelab.ru оригинал источник codelab.ru

Типичная структура объектов: codelab.ru оригинал codelab.ru источник
codelab.ru источник codelab.ru оригинал

оригинал codelab.ru codelab.ru источник

Участники паттерна Посредник (Mediator)

codelab.ru источник codelab.ru оригинал
  1. Mediator (DialogDirector) – посредник.
    Определяет интерфейс для обмена информацией с объектами Colleague. источник codelab.ru codelab.ru оригинал
  2. ConcreteMediator (FontDialogDirector) - конкретный посредник.
    Реализует кооперативное поведение, координируя действия объектов Colleague.
    Владеет информацией о коллегах и подсчитывает их. оригинал источник codelab.ru codelab.ru
  3. Классы Colleague (ListBox, EntryField) – коллеги:
    Каждый класс Colleague «знает» о своем объекте распорядителе Mediator.
    Все коллеги обмениваются информацией только с посредником, так как при его отсутствии им пришлось бы общаться между собой напрямую. codelab.ru источник оригинал codelab.ru

Схема использования паттерна Посредник (Mediator)

Коллеги (Colleague) посылают запросы посреднику (ConcreteMediator) и получают запросы от него. Посредник реализует заданную логику взаимодействия (кооперативное поведение) путем переадресации каждого запроса подходящему коллеге (или сразу нескольким). оригинал источник codelab.ru codelab.ru
codelab.ru источник оригинал codelab.ru

Вопросы, касающиеся реализации паттерна Посредник (Mediator)

Имейте в виду, что при реализации паттерна посредник может происходить: codelab.ru источник оригинал codelab.ru
  1. Избавление от абстрактного класса Mediator.
    Если коллеги работают только с одним посредником, то нет необходимости определять абстрактный класс Mediator. Обеспечиваемая классом Mediator абстракция позволяет коллегам работать с разными подклассами класса Mediator и наоборот. оригинал codelab.ru codelab.ru источник
  2. Обмен информацией между коллегами и посредником.
    Коллеги должны обмениваться информацией со своим посредником только тогда, когда возникает представляющее интерес событие (значимое событие). Одним из подходов к реализации посредника является применение паттерна наблюдатель. Тогда классы коллег действуют как субъекты, посылающие извещения посреднику о любом изменении своего состояния. Посредник реагирует на них, сообщая об этом другим коллегам.
    Другой подход: в классе Mediator определяется специализированный интерфейс уведомления, который позволяет коллегам обмениваться информацией более свободно. оригинал источник codelab.ru codelab.ru

Результаты

С паттерном посредник вы получаете следующие достоинства и недостатки: codelab.ru оригинал источник codelab.ru
  1. Снижает число порождаемых подклассов.
    Посредник локализует, инкапсулирует поведение, которое в противном случае пришлось бы распределять между несколькими объектами. Для изменения поведения нужно породить подклассы только от класса посредника Mediator, классы коллег Colleague можно использовать повторно без каких бы то ни было изменений. источник codelab.ru оригинал codelab.ru
  2. Устраняет связанность между коллегами.
    Посредник обеспечивает слабую связанность коллег. Изменять классы Colleague и Mediator можно теперь независимо друг от друга. оригинал codelab.ru codelab.ru источник
  3. Упрощает протоколы взаимодействия объектов.
    Посредник заменяет дисциплину взаимодействия «все со всеми» дисциплиной «один со всеми», то есть один посредник взаимодействует со всеми коллегами. Отношения вида «один ко многим» проще для понимания, сопровождения и расширения. оригинал codelab.ru источник codelab.ru
  4. Абстрагирует способ кооперирования объектов.
    Выделение механизма посредничества в отдельную концепцию и инкапсуляция ее в одном объекте позволяет сосредоточиться именно на взаимодействии объектов, а не на коррекции их индивидуального поведения. Это дает возможность прояснить имеющиеся в системе взаимодействия. оригинал codelab.ru источник codelab.ru
  5. Централизует управление.
    Паттерн посредник переносит сложность взаимодействия в класс-посредник. Поскольку посредник инкапсулирует протоколы, то он может быть сложнее отдельных коллег. В результате сам посредник становится монолитом, который трудно сопровождать. источник оригинал codelab.ru codelab.ru

Пример

Для создания диалогового окна, обсуждавшегося в разделе мотивация, воспользуемся классом DialogDirector. Абстрактный класс DialogDirector определяет интерфейс распорядителей: DialogDirector. оригинал источник codelab.ru codelab.ru
  codelab.ru codelab.ru оригинал источник
А Widget – это абстрактный базовый класс для всех виджетов. Он располагает информацией о своем распорядителе: Widget. codelab.ru оригинал codelab.ru источник
  источник codelab.ru codelab.ru оригинал
В подклассах DialogDirector переопределена операция WidgetChanged для воздействия на нужные виджеты. Виджет передает ссылку на самого себя в качестве аргумента WidgetChanged, чтобы распорядитель имел информацию об изменившемся виджете. Подклассы DialogDirector переопределяют абстрактную функцию CreateWidgets для размещения в диалоговом окне нужных виджетов. codelab.ru оригинал источник codelab.ru
ListBox, EntryField и Button - это подклассы Widget для специализированных элементов интерфейса. В классе ListBox есть операция GetSelection для получения текущего множества выделенных элементов, а в классе EntryField - операция SetText для помещения текста в поле ввода: ListBox, EntryField. оригинал codelab.ru codelab.ru источник
  источник codelab.ru оригинал codelab.ru
Далее понадобится также кнопка Button (простой виджет). Операция Changed вызывается в операции обработки событий мыши HandleMouse: Button. источник оригинал codelab.ru codelab.ru
  оригинал codelab.ru codelab.ru источник
Класс FontDialogDirector является посредником (ConcreteMediator) между всеми виджетами в диалоговом окне. FontDialogDirector - это подкласс класса DialogDirector: FontDialogDirector. оригинал codelab.ru источник codelab.ru
  оригинал codelab.ru источник codelab.ru
Сложность операции WidgetChanged возрастает пропорционально сложности окна диалога. Создание очень больших диалоговых окон нежелательно и по другим причинам, но в других приложениях сложность посредника может свести на нет его преимущества. codelab.ru codelab.ru оригинал источник
источник codelab.ru оригинал codelab.ru
  источник codelab.ru codelab.ru оригинал
источник codelab.ru оригинал codelab.ru

Известные применения паттерна Посредник (Mediator)

И в ЕТ++, и в библиотеке классов THINK С применяются похожие на нашего распорядителя объекты для осуществления посредничества между виджетами в диалоговых окнах. codelab.ru источник codelab.ru оригинал
Архитектура приложения в Smalltalk/V для Windows основана на структуре посредника. В этой среде приложение состоит из окна Window, которое содержит набор панелей. В библиотеке есть несколько предопределенных объектов-панелей Pane, например: TextPane, ListBox, Button и т.д. Их можно использовать без подклассов. Разработчик приложения порождает подклассы только от класса ViewManager (диспетчер видов), отвечающего за обмен информацией между панелями. ViewManager - это посредник, каждая панель «знает» своего диспетчера, который считается «владельцем» панели. Панели не ссылаются друг на друга напрямую. источник оригинал codelab.ru codelab.ru
В Smalltalk/V для обмена информацией между объектами Pane и ViewManager используется механизм событий. Панель генерирует событие для получения данных от своего посредника или для информирования его о чем-то важном. С каждым событием связан символ (например, #select), который однозначно его идентифицирует. Диспетчер видов регистрирует вместе с панелью селектор метода, который является обработчиком события. codelab.ru источник codelab.ru оригинал
При координации сложных обновлений также требуется паттерн посредник. оригинал codelab.ru источник codelab.ru
Примером может служить класс ChangeManager, упомянутый в описании паттерна наблюдатель. Этот класс осуществляет посредничество между субъектами и наблюдателями, чтобы не делать лишних обновлений. Когда объект изменяется, он извещает ChangeManager, который координирует обновление и информирует все необходимые объекты. codelab.ru codelab.ru источник оригинал
Аналогичным образом посредник применяется в графических редакторах Unidraw [VL90], где используется класс CSolver, следящий за соблюдением ограничений связанности между коннекторами. Объекты в графических редакторах могут быть визуально соединены между собой различными способами. Коннекторы полезны в приложениях, которые автоматически поддерживают связанность, например в редакторах диаграмм и в системах проектирования электронных схем. оригинал источник codelab.ru codelab.ru
Класс CSolver является посредником между коннекторами. Он разрешает ограничения связанности и обновляет позиции коннекторов так, чтобы отразить изменения. codelab.ru источник оригинал codelab.ru
codelab.ru codelab.ru источник оригинал

Родственные паттерны

Фасад отличается от посредника тем, что абстрагирует некоторую подсистему объектов для предоставления более удобного интерфейса. Его протокол однонаправленный, то есть объекты фасада направляют запросы классам подсистемы, но не наоборот. Посредник же обеспечивает совместное поведение, которое объекты-коллеги не могут или не «хотят» реализовывать, и его протокол, таким образом, двунаправленный. оригинал источник codelab.ru codelab.ru
Коллеги могут обмениваться информацией с посредником посредством паттерна наблюдатель. codelab.ru оригинал источник codelab.ru
источник codelab.ru оригинал codelab.ru
codelab.ru источник codelab.ru оригинал


Реализации: java(6)   +добавить реализацию

1) DialogDirector.java, code #507[автор:this]
2) Widget.java, code #509[автор:this]
3) ListBox.java, code #510[автор:this]
4) EntryField.java, code #511[автор:this]
5) Button.java, code #512[автор:this]
6) FontDialogDirector.java, code #513[автор:this]


<< назад наверх
распечатать обсудить >>

 
каталог | задачи | паттерны | исходники | стат | форумы | карта сайта | контакты | ссылки 
© 2000-2017 CodeLAB Group
  Все права защищены
Страница сгенерирована за 0.041297 секунд
Количество запросов к БД: 14, gzip: 19.2kb/96.6kb(81%)