- Посредник (шаблон проектирования)
-
Шаблон проектирования Посредник Mediator Тип: поведенческий
Описан в Design Patterns Да
Шаблон Mediator (также известный как Посредник) – поведенческий шаблон проектирования
Обеспечивает взаимодействие множества объектов, формируя при этом слабую связанность и избавляя объекты от необходимости явно ссылаться друг на друга.
Содержание
Проблема
Обеспечить взаимодействие множества объектов, сформировав при этом слабую связанность и избавив объекты от необходимости явно ссылаться друг на друга.
Решение
Создать объект, инкапсулирующий способ взаимодействия множества объектов.
Преимущества
Устраняется связанность между "Коллегами", централизуется управление.
Структура
UML диаграмма, описывающая структуру шаблона проектирования Посредник- Mediator – "Посредник"
- ConcreteMediator – "Конкретный посредник"
- Классы Colleague – "Коллеги"
Описание
"Посредник" определяет интерфейс для обмена информацией с объектами "Коллеги", "Конкретный посредник" координирует действия объектов "Коллеги". Каждый класс "Коллеги" знает о своем объекте "Посредник", все "Коллеги" обмениваются информацией только с посредником, при его отсутствии им пришлось бы обмениваться информацией напрямую. "Коллеги" посылают запросы посреднику и получают запросы от него. "Посредник" реализует кооперативное поведение, пересылая каждый запрос одному или нескольким "Коллегам".
Примеры
Пример на PHP5
Исходный текст на PHP5//абстрактный класс посредник abstract class Mediator { /** * Отправка сообщения {@code message} указанному получателю {@code colleague} * @param string message отправляемое сообщение * @param Collegue colleague получатель сообщения */ public abstract function send($message, Colleague $collegue); } //абстрактный класс коллега abstract class Colleague { protected $mediator; public function __construct(Mediator $mediator) { $this->mediator = $mediator; } /** * Отправка сообщения посредством посредника * @param string message сообщение */ public function send($message){ $this->mediator->send($message, $this); } /** * Обработка полученного сообщения реализуется каждым конкретным * наследником * @param string message полчаемое сообщение */ public abstract function notify($message); } class ConcreteMediator extends Mediator { private $colleague1; private $colleague2; public function setColleague1(ConcreteColleague1 $colleague){ $this->colleague1 = $colleague; } public function setColleague2(ConcreteColleague2 $colleague){ $this->colleague2 = $colleague; } public function send($message, Colleague $colleague) { if ($colleague == $this->colleague1) { $this->colleague2->notify($message); } else { $this->colleague1->notify($message); } } } //коллега 1 class ConcreteColleague1 extends Colleague { public function notify($message) { echo sprintf("Collegue1 gets message: %s\n", $message); } } //коллега 2 class ConcreteColleague2 extends Colleague { public function notify($message) { echo sprintf("Collegue2 gets message: %s\n", $message); } } $mediator = new ConcreteMediator(); $collegue1 = new ConcreteColleague1($mediator); $collegue2 = new ConcreteColleague2($mediator); $mediator->setColleague1($collegue1); $mediator->setColleague2($collegue2); $collegue1->send('How are you ?'); $collegue2->send('Fine, thanks!');
Пример на Java
Исходный текст на Java/** * Абстрактный класс объектов, взаимодествующих посредством паттерна «Посредник» */ public abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; } /** * Отправка сообщения посредством посредника * @param message сообщение */ public void send(String message) { mediator.Send(message, this); } /** * Обработка полученного сообщения реализуется каждым конкретным * наследником * @param message полчаемое сообщение */ public abstract void notify(String message); } /** * Абстрактный класс "Посредник" */ public abstract class Mediator { /** * Отправка сообщения {@code message} указанному получателю {@code colleague} * @param message отправляемое сообщение * @param colleague получатель сообщения */ public abstract void Send(String message, Colleague colleague); } /** Коллега 1 */ public class ConcreteColleague1 extends Colleague { public ConcreteColleague1(Mediator mediator) { super(mediator); } @Override public void notify(String message) { System.out.println("Colleague1 gets message: " + message); } } /** Коллега 2 */ public class ConcreteColleague2 extends Colleague { public ConcreteColleague2(Mediator mediator) { super(mediator); } @Override public void notify(String message) { System.out.println("Colleague2 gets message: " + message); } } /** * Посредник, реализующий конкретный алгоритм отправки сообщений между двумя * типами получателей {@code ConcreteColleague1} и {@code ConcreteColleague2} */ public class ConcreteMediator extends Mediator { private ConcreteColleague1 colleague1; private ConcreteColleague2 colleague2; public void setColleague1(ConcreteColleague1 colleague) { this.colleague1 = colleague; } public void setColleague2(ConcreteColleague2 colleague) { this.colleague2 = colleague; } @Override public void Send(String message, Colleague colleague) { if (colleague == colleague1) { colleague2.notify(message); } else { colleague1.notify(message); } } } /** Тестовый класс */ public class Main { public static void main(String[] args) { ConcreteMediator m = new ConcreteMediator(); ConcreteColleague1 c1 = new ConcreteColleague1(m); ConcreteColleague2 c2 = new ConcreteColleague2(m); m.setColleague1(c1); m.setColleague2(c2); c1.send("How are you?"); c2.send("Fine, thanks"); } }
Пример на C#
Исходный текст на языке C#// Mediator pattern — Structural example using System; namespace DoFactory.GangOfFour.Mediator.Structural { /// <summary> /// MainApp startup class for Structural /// Mediator Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main() { ConcreteMediator m = new ConcreteMediator(); ConcreteColleague1 c1 = new ConcreteColleague1(m); ConcreteColleague2 c2 = new ConcreteColleague2(m); m.Colleague1 = c1; m.Colleague2 = c2; c1.Send("How are you?"); c2.Send("Fine, thanks"); // Wait for user Console.ReadKey(); } } /// <summary> /// The 'Mediator' abstract class /// </summary> abstract class Mediator { public abstract void Send(string message, Colleague colleague); } /// <summary> /// The 'ConcreteMediator' class /// </summary> class ConcreteMediator : Mediator { private ConcreteColleague1 _colleague1; private ConcreteColleague2 _colleague2; public ConcreteColleague1 Colleague1 { set { _colleague1 = value; } } public ConcreteColleague2 Colleague2 { set { _colleague2 = value; } } public override void Send(string message, Colleague colleague) { if (colleague == _colleague1) { _colleague2.Notify(message); } else { _colleague1.Notify(message); } } } /// <summary> /// The 'Colleague' abstract class /// </summary> abstract class Colleague { protected Mediator mediator; // Constructor public Colleague(Mediator mediator) { this.mediator = mediator; } } /// <summary> /// A 'ConcreteColleague' class /// </summary> class ConcreteColleague1 : Colleague { // Constructor public ConcreteColleague1(Mediator mediator) : base(mediator) { } public void Send(string message) { mediator.Send(message, this); } public void Notify(string message) { Console.WriteLine("Colleague1 gets message: " + message); } } /// <summary> /// A 'ConcreteColleague' class /// </summary> class ConcreteColleague2 : Colleague { // Constructor public ConcreteColleague2(Mediator mediator) : base(mediator) { } public void Send(string message) { mediator.Send(message, this); } public void Notify(string message) { Console.WriteLine("Colleague2 gets message: " + message); } } } Output Colleague2 gets message: How are you? Colleague1 gets message: Fine, thanks
Пример на C++
Исходный текст на языке C++#include <iostream> class Colleague; class Mediator; class ConcreteMediator; class ConcreteColleague1; class ConcreteColleague2; class Mediator { public: virtual void Send(std::string message, Colleague *colleague)=0; }; class Colleague { protected: Mediator *mediator; public: Colleague(Mediator *mediator) { this->mediator=mediator; } }; class ConcreteColleague1:public Colleague { public: ConcreteColleague1(Mediator *mediator):Colleague(mediator) { } void Send(std::string message) { mediator->Send(message, this); } void Notify(std::string message) { std::cout << "Colleague1 gets message " << message.c_str() << std::endl; } }; class ConcreteColleague2:public Colleague { public: ConcreteColleague2(Mediator *mediator):Colleague(mediator) { } void Send(std::string message) { mediator->Send(message, this); } void Notify(std::string message) { std::cout << "Colleague2 gets message " << message.c_str() << std::endl; } }; class ConcreteMediator:public Mediator { protected: ConcreteColleague1 *m_Colleague1; ConcreteColleague2 *m_Colleague2; public: void SetColleague1(ConcreteColleague1 *c) { m_Colleague1=c; } void SetColleague2(ConcreteColleague2 *c) { m_Colleague2=c; } virtual void Send(std::string message, Colleague *colleague) { if (colleague==static_cast<Colleague*>(m_Colleague1)) { m_Colleague2->Notify(message); } else if (colleague==static_cast<Colleague*>(m_Colleague2)) { m_Colleague1->Notify(message); } } }; int main(int argc, char **argv) { ConcreteMediator *m = new ConcreteMediator(); ConcreteColleague1 *c1 = new ConcreteColleague1(m); ConcreteColleague2 *c2 = new ConcreteColleague2(m); m->SetColleague1(c1); m->SetColleague2(c2); c1->Send("How are you?"); c2->Send("Fine, thanks"); std::cin.get(); return 0; } Output Colleague2 gеts message How are you? Colleague1 gеts message Fine, thanks
Пример на Delphi
Исходный текст на языке Delphiprogram MediatorExample; {$APPTYPE CONSOLE} type IColleague = interface procedure Send(AMessage: string); procedure Notify(AMessage: string); end; type TMediator = class procedure Send(AMessage: string; ACollegue:IColleague);virtual;abstract; end; TConcreteMediator = class(TMediator) public FCollegue1:IColleague; FCollegue2:IColleague; procedure Send(AMessage: string; ACollegue:IColleague);override; end; type TColleague = class(TInterfacedObject, IColleague) public FMediator: TMediator; constructor Create(AMediator: TMediator); procedure Send(AMessage: string);virtual;abstract; procedure Notify(AMessage: string);virtual;abstract; end; ConcreteColleague1 = class(TColleague) procedure Send(AMessage: string);override; procedure Notify(AMessage: string);override; end; ConcreteColleague2 = class(TColleague) procedure Send(AMessage: string);override; procedure Notify(AMessage: string);override; end; { TConcreteMediator } procedure TConcreteMediator.Send(AMessage: string; ACollegue:IColleague); begin if (ACollegue = FCollegue1) then FCollegue2.Notify(AMessage) else FCollegue1.Notify(AMessage); end; { TColleague } constructor TColleague.Create(AMediator: TMediator); begin FMediator := AMediator; end; { ConcreteColleague1 } procedure ConcreteColleague1.Send(AMessage: string); begin FMediator.Send(AMessage, self); end; procedure ConcreteColleague1.Notify(AMessage: string); begin Writeln('Colleague1 gets message: ' + AMessage); end; { ConcreteColleague2 } procedure ConcreteColleague2.Send(AMessage: string); begin FMediator.Send(AMessage, self); end; procedure ConcreteColleague2.Notify(AMessage: string); begin Writeln('Colleague2 gets message: ' + AMessage); end; var Mediator: TConcreteMediator; Colleague1: ConcreteColleague1; Colleague2: ConcreteColleague2; begin Mediator := TConcreteMediator.Create; Colleague1 := ConcreteColleague1.Create(Mediator); Colleague2 := ConcreteColleague2.Create(Mediator); Mediator.FCollegue1 := Colleague1; Mediator.FCollegue2 := Colleague2; Colleague1.Send('How are you?'); Colleague2.Send('Fine, thanks'); Readln; end.
Ссылки
- Паттерн Mediator (посредник) — назначение, описание, особенности и реализация на С++.
Шаблоны проектирования Основные Порождающие Структурные Поведенческие Интерпретатор • Итератор • Команда • Наблюдатель • Посетитель • Посредник • Состояние • Стратегия • Хранитель • Цепочка обязанностей • Шаблонный метод
Блокировка с двойной проверкой • Однопоточное выполнение • Планировщик Категория:- Шаблоны проектирования
Wikimedia Foundation. 2010.