stringtranslate.com

Модель посредника

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

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

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

Обзор

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

Проблемы, которые может решить шаблон проектирования «Медиатор»[2]

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

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

Решения, описанные шаблоном проектирования посредника

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

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

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

Определение

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

Структура

Диаграмма классов и последовательностей UML

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

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

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

Предполагая, что Colleague1требуется взаимодействовать с Colleague2(например, обновить/синхронизировать его состояние), Colleague1вызывается mediate(this)объект Mediator1, который получает измененные данные Colleague1и выполняет action2()on Colleague2.

После этого Colleague2вызывается mediate(this)объект Mediator1, который получает измененные данные Colleague2и выполняет action1()on Colleague1.

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

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

Посредник — определяет интерфейс для связи между объектами Colleague .

ConcreteMediator - реализует интерфейс посредника и координирует коммуникацию между объектами Colleague . Он знает обо всех Colleague и их целях в отношении межкоммуникации.

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

ConcreteColleague — реализует интерфейс Colleague и общается с другими Colleague через своего посредника.

Пример

С#

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

интерфейс IComponent { void SetState ( состояние объекта ); }    класс Component1 : IComponent { внутренний void SetState ( состояние объекта ) { throw new NotImplementedException (); } }            класс Component2 : IComponent { внутренний void SetState ( состояние объекта ) { throw new NotImplementedException (); } }            // Выполняет общие задачи class Mediator { internal IComponent Component1 { get ; set ; } internal IComponent Component2 { get ; set ; }                внутренний void ChangeState ( состояние объекта ) { этот.Компонент1.УстановитьСостояние ( состояние ) ; этот.Компонент2.УстановитьСостояние ( состояние ) ; } }       

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

открытый делегат void MessageReceivedEventHandler ( string message , string sender );      public class Mediator { public event MessageReceivedEventHandler MessageReceived ;       public void Send ( string message , string sender ) { if ( MessageReceived != null ) { Console.WriteLine ( " Отправка '{0}' от {1}" , message , sender ) ; MessageReceived ( message , sender ); } } }                  публичный класс Персона { частный Посредник _медиатор ;      Имя публичной строки { получить ; установить ; }       public Person ( Mediator mediator , string name ) { Name = name ; _mediator = mediator ; _mediator.MessageReceived + = new MessageReceivedEventHandler ( Receive ) ; }                 private void Receive ( string message , string sender ) { if ( sender != Name ) Console.WriteLine ( " {0} получил '{1}' от {2}" , Name , message , sender ) ; }                public void Send ( string message ) { _mediator.Send ( message , Name ) ; } }       

Ява

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

импорт java.util.HashMap ; импорт java.util.Optional ; импорт java.util.concurrent.CopyOnWriteArrayList ; импорт java.util.function.Consumer ;    class  Storage < T > { T value ; T getValue () { return value ; } void setValue ( Mediator < T > mediator , String storageName , T value ) { this . value = value ; mediator . notifyObservers ( storageName ); } }                       class  Mediator < T > { private final HashMap < String , Storage < T >> storageMap = new HashMap < > ( ); private final CopyOnWriteArrayList < Consumer < String >> observers = new CopyOnWriteArrayList <> (); public void setValue ( String storageName , T value ) { Storage storage = storageMap.computeIfAbsent ( storageName , name - > new Storage < > ()); storage.setValue ( this , storageName , value ) ; } public Optional < T > getValue ( String storageName ) { return Optional.ofNullable ( storageMap.get ( storageName ) ) . map ( Storage :: getValue ) ; } public void addObserver ( String storageName , Runnable observer ) { observers.add ( eventName - > { if ( storageName.equals ( storageName ) ) { observer.run ( ) ; } } ) ; } void notifyObservers ( String eventName ) { observers.forEach ( observer - > observer.accept ( eventName ) ) ; } }                                                                        public class MediatorDemo { public static void main ( String [] args ) { Mediator < Integer > mediator = new Mediator <> (); mediator.setValue ( " боб " , 20 ); mediator.setValue ( " элиса " , 24 ); mediator.getValue ( "элиса" ) .ifPresent ( age -> System.out.println ( " возраст для элис: " + age ) ); mediator.addObserver ( " боб " , ( ) - > { System.out.println ( " новый возраст для боба : " + mediator.getValue ( " боб " ) .orElseThrow ( RuntimeException :: new )); }); mediator.setValue ( " боб " , 21 ) ; } }                                   

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

Ссылки

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

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