Шаблон посредника - Mediator pattern

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

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

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

Обзор

Посредник[1] шаблон дизайна - один из двадцати трех хорошо известных шаблоны проектирования в которых описывается, как решать повторяющиеся проблемы проектирования для разработки гибкого и многократно используемого объектно-ориентированного программного обеспечения, то есть объектов, которые легче реализовать, изменить, протестировать и повторно использовать.

Какие проблемы может решить шаблон проектирования Посредник?[2]

  • Следует избегать тесной связи между набором взаимодействующих объектов.
  • Должна существовать возможность изменять взаимодействие между набором объектов независимо.

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

Сильно связанные объекты их сложно реализовать, изменить, протестировать и повторно использовать, потому что они относятся к множеству различных объектов и знают о них.

Какое решение описывает шаблон проектирования Посредник?

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

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

Это делает объекты слабо связанный. Они только ссылаются на свой объект-посредник и знают о нем и не имеют явного знания друг о друге.

См. Также схему классов и последовательности UML ниже.

Определение

Суть паттерна посредника состоит в том, чтобы «определить объект, который инкапсулирует, как взаимодействует набор объектов». Он способствует слабой связи, не позволяя объектам явно ссылаться друг на друга, и позволяет изменять их взаимодействие независимо друг от друга.[3][4] Классы клиентов могут использовать посредника для отправки сообщений другим клиентам и могут получать сообщения от других клиентов через событие в классе посредника.

Структура

Схема классов и последовательности UML

Пример класса UML и диаграмма последовательности для шаблона проектирования посредник.[5]

В приведенном выше UML диаграмма классов, то Коллега1 и Коллега2 классы не ссылаются (и не обновляют) друг друга напрямую, а вместо этого относятся к общим Посредник интерфейс для управления и координации взаимодействия (посредничать ()), что делает их независимыми друг от друга в том, как осуществляется взаимодействие. Посредник1 класс реализует взаимодействие между Коллега1 и Коллега2.

В UML схема последовательности показывает взаимодействия во время выполнения. В этом примере Посредник1 объект опосредует (контролирует и координирует) взаимодействие между Коллега1 и Коллега2 объекты.

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

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

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

Шаблон поведенческого проектирования посредника
Участников

Посредник - определяет интерфейс для связи между Коллега объекты

БетонМедиатор - реализует интерфейс посредника и координирует связь между Коллега объекты. Он знает обо всех Коллеги по работе и их цели в отношении взаимодействия.

Коллега - определяет интерфейс для связи с другими Коллеги по работе через его Посредник

БетонКоллига - реализует интерфейс Коллеги и общается с другими Коллеги по работе через его Посредник

пример

C #

Шаблон посредника гарантирует, что компоненты слабо связанный, так что они не вызывают друг друга явно, а вместо этого делают это через вызовы посредника. В следующем примере посредник регистрирует все компоненты, а затем вызывает их методы SetState.

интерфейс IComponent{    пустота SetState(объект штат);}класс Компонент1 : IComponent{    внутренний пустота SetState(объект штат)    {        бросить новый NotImplementedException();    }}класс Компонент2 : IComponent{    внутренний пустота SetState(объект штат)    {        бросить новый NotImplementedException();    }}// Выполняет общие задачикласс Посредник{    внутренний IComponent Компонент1 { получать; набор; }    внутренний IComponent Компонент2 { получать; набор; }    внутренний пустота ChangeState(объект штат)    {        этот.Компонент1.SetState(штат);        этот.Компонент2.SetState(штат);    }}

В чате можно использовать шаблон «Посредник» или систему, в которой каждый из многих «клиентов» получает сообщение каждый раз, когда один из других клиентов выполняет какое-либо действие (для чатов это будет когда каждый человек отправляет сообщение). На самом деле использование шаблона Посредника для чата будет практичным только при использовании с удаленное взаимодействие. Использование сырых сокетов не позволит делегировать обратные вызовы (люди подписались на событие MessageReceived класса Mediator).

общественный делегировать пустота MessageReceivedEventHandler(строка сообщение, строка отправитель);общественный класс Посредник{    общественный мероприятие MessageReceivedEventHandler Сообщение доставлено;    общественный пустота послать(строка сообщение, строка отправитель)    {        если (Сообщение доставлено != значение NULL)        {            Консоль.WriteLine("Отправка '{0}' от {1}", сообщение, отправитель);            Сообщение доставлено(сообщение, отправитель);        }    }}общественный класс Человек{    частный Посредник _mediator;    общественный строка имя { получать; набор; }    общественный Человек(Посредник посредник, строка имя)    {        имя = имя;        _mediator = посредник;        _mediator.Сообщение доставлено += новый MessageReceivedEventHandler(Получить);    }    частный пустота Получить(строка сообщение, строка отправитель)    {        если (отправитель != имя)            Консоль.WriteLine("{0} получил '{1}' от {2}", имя, сообщение, отправитель);    }    общественный пустота послать(строка сообщение)    {        _mediator.послать(сообщение, имя);    }}

Ява

В следующем примере Посредник объект управляет значениями нескольких Место хранения объекты, заставляя код пользователя обращаться к сохраненным значениям через посредника. Когда объект хранения хочет создать событие, указывающее, что его значение изменилось, он также возвращается к объекту-посреднику (через метод notifyObservers), который управляет списком наблюдателей (реализован с помощью образец наблюдателя ).

импорт java.util.HashMap;импорт java.util.Optional;импорт java.util.concurrent.CopyOnWriteArrayList;импорт java.util.function.Consumer;класс Место хранения<Т> {    Т ценность;        Т getValue() {        вернуть ценность;    }    пустота setValue(Посредник<Т> посредник, Строка storageName, Т ценность) {        этот.ценность = ценность;        посредник.notifyObservers(storageName);    }}класс Посредник<Т> {    частный окончательный HashMap<Строка, Место хранения<Т>> StorageMap = новый HashMap<>();    частный окончательный CopyOnWriteArrayList<Потребитель<Строка>> наблюдатели = новый CopyOnWriteArrayList<>();        общественный пустота setValue(Строка storageName, Т ценность) {        Место хранения место хранения = StorageMap.computeIfAbsent(storageName, имя -> новый Место хранения<>());        место хранения.setValue(этот, storageName, ценность);    }        общественный Необязательный<Т> getValue(Строка storageName) {        вернуть Необязательный.ofNullable(StorageMap.получать(storageName)).карта(Место хранения::getValue);    }        общественный пустота addObserver(Строка storageName, Работоспособен наблюдатель) {        наблюдатели.Добавить(название события -> {            если (название события.равно(storageName)) {                наблюдатель.бегать();            }        });    }        пустота notifyObservers(Строка название события) {        наблюдатели.для каждого(наблюдатель -> наблюдатель.принять(название события));    }}общественный класс ПосредникДемо {    общественный статический пустота основной(Строка[] аргументы) {        Посредник<Целое число> посредник = новый Посредник<>();        посредник.setValue("боб", 20);        посредник.setValue("алиса", 24);        посредник.getValue("алиса").если имеется(возраст -> Система.вне.println("возраст для Алисы:" + возраст));                посредник.addObserver("боб", () -> {            Система.вне.println("новый век для боба:" + посредник.getValue("боб").orElseThrow(RuntimeException::новый));        });        посредник.setValue("боб", 21);    }}

Смотрите также

использованная литература

  1. ^ Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссидес (1994). Паттерны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования. Эддисон Уэсли. стр.273ff. ISBN  0-201-63361-2.CS1 maint: несколько имен: список авторов (ссылка на сайт)
  2. ^ Франке, Гюнтер. «Шаблон проектирования посредника - проблема, решение и применимость». w3sDesign. Получено 2017-08-12.
  3. ^ Гамма, Эрих; Хелм, Ричард; Джонсон, Ральф; Влиссидес, Джон (1994). Шаблоны проектирования. Эддисон-Уэсли. ISBN  0-201-63361-2.
  4. ^ "Шаблон дизайна посредника". Источник.
  5. ^ Франке, Гюнтер. «Шаблон проектирования посредника - структура и взаимодействие». w3sDesign. Получено 2017-08-12.

внешние ссылки