- Посредник (шаблон проектирования)
-
Шаблон проектирования Посредник Mediator Тип: поведенческий
Описан в Design Patterns Да
Шаблон Mediator (также известный как Посредник) – поведенческий шаблон проектирования
Обеспечивает взаимодействие множества объектов, формируя при этом слабую связанность и избавляя объекты от необходимости явно ссылаться друг на друга.
Содержание
Проблема
Обеспечить взаимодействие множества объектов, сформировав при этом слабую связанность и избавив объекты от необходимости явно ссылаться друг на друга.
Решение
Создать объект, инкапсулирующий способ взаимодействия множества объектов.
Преимущества
Устраняется связанность между "Коллегами", централизуется управление.
Структура
- 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.