Посередник (англ. Mediator) — шаблон проєктування, наледжить до класу шаблонів поведінки.
Призначення
Визначає об'єкт, що інкапсулює спосіб взаємодії множини об'єктів. Посередник забезпечує слабку зв'язаність системи, звільняючи об'єкти від необхідності явно посилатися один на одного, і дозволяючи тим самим незалежно змінювати взаємодії між ними.
Застосовність
Слід використовувати шаблон Посередник у випадках, коли:
- існують об'єкти, зв'язки між котрими досить складні та чітко задані. Отримані при цьому залежності не структуровані та важкі для розуміння;
- не можна повторно використовувати об'єкт, оскільки він обмінюється інформацією з багатьма іншими об'єктами;
- поведінка, розподілена між кількома класами, повинна піддаватися налагодженню без створювання множини підкласів.
Структура
- Mediator — посередник:
- визначає інтерфейс для обміну інформацією з об'єктами Colleague;
- ConcreteMediator — конкретний посередник:
- реалізує кооперативну поведінку, координуючи дії об'єктів Colleague;
- володіє інформацією про колег, та підраховує їх;
- Класи Colleague — колеги:
- кожному класу Colleague відомо про свій об'єкт Mediator;
- усі колеги обмінюються інформацією виключно через посередника, інакше за його відсутності їм довелося б спілкуватися між собою напряму.
Відносини
Колеги посилають запити посередникові та отримують запити від нього. Посередник реалізує кооперативну поведінку шляхом переадресації кожного запиту відповідному колезі (або декільком з них).
Переваги та недоліки
Переваги
- Медіатор вказує логіку посередництва між колегами. З цієї причини це легше зрозуміти цю логіку, оскільки вона зберігається лише в одному класі.
- Класи колег повністю відокремлені. Додавання нового класу колеги дуже легко через цей рівень роз'єднання.
- Об'єкти колеги повинні спілкуватися лише з об'єктами посередника. Практично модель медіатора зменшує необхідні канали зв'язку (протоколи) від багатьох до багатьох до одного до багатьох і багатьох до одного.
- Оскільки вся логіка зв'язку вказується класом посередника, коли ця логіка потребує розширення, лише клас посередника потрібно розширити.
Недоліки
- Складність — на практиці посередники стають все більш складними та складними
Зв'язок із іншими патернами
- Посередник створює двосторонній зв'язок, часто незмінний. Забирає залежності між компонентами системи. Компоненти стають залежними від посередника. Спостерігач створює односторонній зв'язок, який може мінятись під час виконання програми. Таким чином одні об'єкти залежать від інших.
Приклади
C++
#include <iostream> #include <string> using namespace std; class Colleague; class Mediator; class ConcreteMediator; class ConcreteColleague1; class ConcreteColleague2; struct Mediator { virtual void Send(string const& message, Colleague *colleague) const = 0; }; class Colleague { protected: Mediator* mediator; public: explicit Colleague(Mediator *mediator) :mediator(mediator) {} }; struct ConcreteColleague1 :public Colleague { explicit ConcreteColleague1(Mediator* mediator) :Colleague(mediator) {} void Send(string const& message) { mediator->Send(message, this); } void Notify(string const& message) { cout << "Colleague1 gets message '" << message << "'" << endl; } }; struct ConcreteColleague2 :public Colleague { explicit ConcreteColleague2(Mediator *mediator) :Colleague(mediator) {} void Send(string const& message) { mediator->Send(message, this); } void Notify(string const& message) { cout << "Colleague2 gets message '" << message << "'" << 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(string const& message, Colleague *colleague) const { if (colleague == m_Colleague1) { m_Colleague2->Notify(message); } else if (colleague == m_Colleague2) { m_Colleague1->Notify(message); } } }; void main() { ConcreteMediator m; ConcreteColleague1 c1(&m); ConcreteColleague2 c2(&m); m.SetColleague1(&c1); m.SetColleague2(&c2); c1.Send("How are you?"); c2.Send("Fine, thanks"); }
C#
using System; using System.Linq; using System.Collections.Generic; namespace MediatorPattern { public interface IMediator { void AddParticipant(IParticipant participant); void BroadcastMessage(string message, IParticipant sender); } public class ConcreteMediator : IMediator { private readonly ICollection<IParticipant> _participants = new List<IParticipant>(); public void AddParticipant(IParticipant participant) { _participants.Add(participant); } public void BroadcastMessage(string message, IParticipant sender) { foreach (var participant in _participants.Where(p => p != sender)) { participant.HandleMessage(message); } } } public interface IParticipant { void SendMessage(string message); void HandleMessage(string message); } public class ConcreteParticipant : IParticipant { private readonly int _id; protected readonly IMediator _mediator; public ConcreteParticipant(int id, IMediator mediator) { _id = id; _mediator = mediator; } public void SendMessage(string message) { Console.WriteLine($"Participant {_id} send message: {message}"); _mediator.BroadcastMessage(message, this); } public void HandleMessage(string message) { Console.WriteLine($"Participant {_id} recieve message: {message}"); } } class Program { static void Main(string[] args) { IMediator mediator = new ConcreteMediator(); IParticipant participant1 = new ConcreteParticipant(1, mediator); IParticipant participant2 = new ConcreteParticipant(2, mediator); IParticipant participant3 = new ConcreteParticipant(3, mediator); mediator.AddParticipant(participant1); mediator.AddParticipant(participant2); mediator.AddParticipant(participant3); participant1.SendMessage("Hello from first participant"); participant2.SendMessage("Hello from second participant"); } } }
using System; using System.Collections.Generic; namespace MediatorPattern { public interface IMediator<TEvent> where TEvent : EventArgs { void AddHandler(IParticipantHandler<TEvent> participant); void BroadcastMessage(TEvent eventArgs); } public class UserCreatedEventArgs : EventArgs { public string User { get; set; } } public class UserMediator : IMediator<UserCreatedEventArgs> { private readonly ICollection<IParticipantHandler<UserCreatedEventArgs>> _participants = new List<IParticipantHandler<UserCreatedEventArgs>>(); public void AddHandler(IParticipantHandler<UserCreatedEventArgs> participant) { _participants.Add(participant); } public void BroadcastMessage(UserCreatedEventArgs eventArgs) { foreach (var participant in _participants) { participant.HandleEvent(eventArgs); } } } public class ReportUpdatedEventArgs : EventArgs { } public class ReportMediator : IMediator<ReportUpdatedEventArgs> { private readonly ICollection<IParticipantHandler<ReportUpdatedEventArgs>> _participants = new List<IParticipantHandler<ReportUpdatedEventArgs>>(); public void AddHandler(IParticipantHandler<ReportUpdatedEventArgs> participant) { _participants.Add(participant); } public void BroadcastMessage(ReportUpdatedEventArgs eventArgs) { foreach (var participant in _participants) { participant.HandleEvent(eventArgs); } } } public interface IParticipantHandler<T> where T : EventArgs { void HandleEvent(T message); } public interface IParticipantProducer<T> where T : EventArgs { void SendMessage(T message); } public class DbParticipant : IParticipantProducer<UserCreatedEventArgs> { protected readonly IMediator<UserCreatedEventArgs> _mediator; public DbParticipant(IMediator<UserCreatedEventArgs> mediator) { _mediator = mediator; } public void SendMessage(UserCreatedEventArgs message) { _mediator.BroadcastMessage(message); } public void AddUser(string newUser) { SendMessage(new UserCreatedEventArgs { User = newUser }); } } public class ReportBuilderParticipant : IParticipantProducer<ReportUpdatedEventArgs>, IParticipantHandler<UserCreatedEventArgs> { protected readonly IMediator<ReportUpdatedEventArgs> _mediator; public ReportBuilderParticipant(IMediator<ReportUpdatedEventArgs> mediator) { _mediator = mediator; } public void HandleEvent(UserCreatedEventArgs message) { UpdateReport(message); } private void UpdateReport(UserCreatedEventArgs message) { Console.WriteLine($"[Report] Add to report new user: {message.User}"); SendMessage(new ReportUpdatedEventArgs()); } public void SendMessage(ReportUpdatedEventArgs message) { _mediator.BroadcastMessage(message); } } public class NotificationParticipant : IParticipantHandler<ReportUpdatedEventArgs>, IParticipantHandler<UserCreatedEventArgs> { protected readonly IMediator<ReportUpdatedEventArgs> _mediator; public NotificationParticipant(IMediator<ReportUpdatedEventArgs> mediator) { _mediator = mediator; } public void HandleEvent(ReportUpdatedEventArgs message) { Console.WriteLine("[Notification] Report is updated and ready to download"); } public void HandleEvent(UserCreatedEventArgs message) { Console.WriteLine($"[Notification] User {message.User} joined chat"); } } class Program { static void Main(string[] args) { IMediator<UserCreatedEventArgs> userMediator = new UserMediator(); IMediator<ReportUpdatedEventArgs> reportMediator = new ReportMediator(); var db = new DbParticipant(userMediator); var reportBuilder = new ReportBuilderParticipant(reportMediator); var notificationSystem = new NotificationParticipant(reportMediator); userMediator.AddHandler(reportBuilder); userMediator.AddHandler(notificationSystem); reportMediator.AddHandler(notificationSystem); db.AddUser("John Doe"); } } }
Java
import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; //Colleague interface interface Command { void execute(); } //Abstract Mediator interface Mediator { void book(); void view(); void search(); void registerView(BtnView v); void registerSearch(BtnSearch s); void registerBook(BtnBook b); void registerDisplay(LblDisplay d); } //Concrete mediator class ParticipantMediator implements Mediator { BtnView btnView; BtnSearch btnSearch; BtnBook btnBook; LblDisplay show; //.... public void registerView(BtnView v) { btnView = v; } public void registerSearch(BtnSearch s) { btnSearch = s; } public void registerBook(BtnBook b) { btnBook = b; } public void registerDisplay(LblDisplay d) { show = d; } public void book() { btnBook.setEnabled(false); btnView.setEnabled(true); btnSearch.setEnabled(true); show.setText("booking..."); } public void view() { btnView.setEnabled(false); btnSearch.setEnabled(true); btnBook.setEnabled(true); show.setText("viewing..."); } public void search() { btnSearch.setEnabled(false); btnView.setEnabled(true); btnBook.setEnabled(true); show.setText("searching..."); } } //A concrete colleague class BtnView extends JButton implements Command { Mediator med; BtnView(ActionListener al, Mediator m) { super("View"); addActionListener(al); med = m; med.registerView(this); } public void execute() { med.view(); } } //A concrete colleague class BtnSearch extends JButton implements Command { Mediator med; BtnSearch(ActionListener al, Mediator m) { super("Search"); addActionListener(al); med = m; med.registerSearch(this); } public void execute() { med.search(); } } //A concrete colleague class BtnBook extends JButton implements Command { Mediator med; BtnBook(ActionListener al, Mediator m) { super("Book"); addActionListener(al); med = m; med.registerBook(this); } public void execute() { med.book(); } } class LblDisplay extends JLabel { Mediator med; LblDisplay(Mediator m) { super("Just start..."); med = m; med.registerDisplay(this); setFont(new Font("Arial", Font.BOLD, 24)); } } class MediatorDemo extends JFrame implements ActionListener { Mediator med = new ParticipantMediator(); MediatorDemo() { JPanel p = new JPanel(); p.add(new BtnView(this, med)); p.add(new BtnBook(this, med)); p.add(new BtnSearch(this, med)); getContentPane().add(new LblDisplay(med), "North"); getContentPane().add(p, "South"); setSize(400, 200); setVisible(true); } public void actionPerformed(ActionEvent ae) { Command comd = (Command) ae.getSource(); comd.execute(); } public static void main(String[] args) { new MediatorDemo(); } }
Python
""" Типовий приклад посередника зустрічається у фреймворку(програмному каркасі) автоматизованого тестування який складається з чотиртох класів: TC (TestCategory), TestManager, Reporter DB(Database) """ import time class TC: def __init__(self): self._tm = tm self._bProblem = 0 def setup(self): print("Setting up the Test") time.sleep(1) self._tm.prepareReporting() def execute(self): if not self._bProblem: print("Executing the test") time.sleep(1) else: print("Problem in setup. Test not executed.") def tearDown(self): if not self._bProblem: print("Tearing down") time.sleep(1) self._tm.publishReport() else: print("Test not executed. No tear down required.") def setTM(self,TM): self._tm = tm def setProblem(self, value): self._bProblem = value class Reporter: def __init__(self): self._tm = None def prepare(self): print("Reporter Class is preparing to report the results") time.sleep(1) def report(self): print("Reporting the results of Test") time.sleep(1) def setTM(self,TM): self._tm = tm class DB: def __init__(self): self._tm = None def insert(self): print("Inserting the execution begin status in the Database") time.sleep(1) #Following code is to simulate a communication from DB to TC import random if random.randrange(1,4) == 3: return -1 def update(self): print("Updating the test results in Database") time.sleep(1) def setTM(self,TM): self._tm = tm class TestManager: def __init__(self): self._reporter = None self._db = None self._tc = None def prepareReporting(self): rvalue = self._db.insert() if rvalue == -1: self._tc.setProblem(1) self._reporter.prepare() def setReporter(self, reporter): self._reporter = reporter def setDB(self, db): self._db = db def publishReport(self): self._db.update() rvalue = self._reporter.report() def setTC(self,tc): self._tc = tc if __name__ == '__main__': reporter = Reporter() db = DB() tm = TestManager() tm.setReporter(reporter) tm.setDB(db) reporter.setTM(tm) db.setTM(tm) # For simplification we are looping on the same test. # Practically, it could be about various unique test classes and their objects while (1): tc = TC() tc.setTM(tm) tm.setTC(tc) tc.setup() tc.execute() tc.tearDown()
TypeScript
@Injectable() class EventMediator { private customerChangedSubject$ = new BehaviorSubject<CustomerData>(null); public customerChanged = this.customerChangedSubject$.asObservable(); public notifyOnCustomerChanged(customerData: CustomerData): void { this.customerChangedSubject$.next(customerData); } private productChangedSubject$ = new BehaviorSubject<ProductData>(null); public productChanged = this.productChangedSubject$.asObservable(); public notifyOnProductChanged(productData: ProductData): void { this.productChangedSubject$.next(productData); } } // надсилання подій this.eventMediator.notifyOnCustomerChanged(new CustomerData()); // обробка подій this.eventMediator.customerChanged.subscribe(c => this.customer = c);
enum Events { CustomerSelected } class EmitEvent{ constructor(public name: Events, value?: any) { } } @Injectable() class EventBus { private subject = new Subject<any>(); on(event: Events, action: any): Subscription { return this.subject .pipe( filter((e: EmitEvent) => e.name === event), map((e: EmitEvent) => e.value), ).subscribe(action); } emit(event: EmitEvent): void { this.subject.next(event); } } // надсилання подій this.eventBus.emit(new EmitEvent(Events.CustomerSelected), new CustomerData()); // обробка подій this.eventBus.on(Events.CustomerSelected, c => this.customer = c);
Джерела
- Design Patterns: Elements of Reusable Object-Oriented Software [ 9 листопада 2012 у Wayback Machine.]
Література
Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — .
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Poserednik angl Mediator shablon proyektuvannya naledzhit do klasu shabloniv povedinki PriznachennyaViznachaye ob yekt sho inkapsulyuye sposib vzayemodiyi mnozhini ob yektiv Poserednik zabezpechuye slabku zv yazanist sistemi zvilnyayuchi ob yekti vid neobhidnosti yavno posilatisya odin na odnogo i dozvolyayuchi tim samim nezalezhno zminyuvati vzayemodiyi mizh nimi ZastosovnistSlid vikoristovuvati shablon Poserednik u vipadkah koli isnuyut ob yekti zv yazki mizh kotrimi dosit skladni ta chitko zadani Otrimani pri comu zalezhnosti ne strukturovani ta vazhki dlya rozuminnya ne mozhna povtorno vikoristovuvati ob yekt oskilki vin obminyuyetsya informaciyeyu z bagatma inshimi ob yektami povedinka rozpodilena mizh kilkoma klasami povinna piddavatisya nalagodzhennyu bez stvoryuvannya mnozhini pidklasiv StrukturaUML diagrama sho opisuye strukturu shablonu proyektuvannya PoserednikMediator poserednik viznachaye interfejs dlya obminu informaciyeyu z ob yektami Colleague ConcreteMediator konkretnij poserednik realizuye kooperativnu povedinku koordinuyuchi diyi ob yektiv Colleague volodiye informaciyeyu pro koleg ta pidrahovuye yih Klasi Colleague kolegi kozhnomu klasu Colleague vidomo pro svij ob yekt Mediator usi kolegi obminyuyutsya informaciyeyu viklyuchno cherez poserednika inakshe za jogo vidsutnosti yim dovelosya b spilkuvatisya mizh soboyu napryamu VidnosiniKolegi posilayut zapiti poserednikovi ta otrimuyut zapiti vid nogo Poserednik realizuye kooperativnu povedinku shlyahom pereadresaciyi kozhnogo zapitu vidpovidnomu kolezi abo dekilkom z nih Perevagi ta nedolikiPerevagi Mediator vkazuye logiku poserednictva mizh kolegami Z ciyeyi prichini ce legshe zrozumiti cyu logiku oskilki vona zberigayetsya lishe v odnomu klasi Klasi koleg povnistyu vidokremleni Dodavannya novogo klasu kolegi duzhe legko cherez cej riven roz yednannya Ob yekti kolegi povinni spilkuvatisya lishe z ob yektami poserednika Praktichno model mediatora zmenshuye neobhidni kanali zv yazku protokoli vid bagatoh do bagatoh do odnogo do bagatoh i bagatoh do odnogo Oskilki vsya logika zv yazku vkazuyetsya klasom poserednika koli cya logika potrebuye rozshirennya lishe klas poserednika potribno rozshiriti Nedoliki Skladnist na praktici poseredniki stayut vse bilsh skladnimi ta skladnimiZv yazok iz inshimi paternamiPoserednik stvoryuye dvostoronnij zv yazok chasto nezminnij Zabiraye zalezhnosti mizh komponentami sistemi Komponenti stayut zalezhnimi vid poserednika Sposterigach stvoryuye odnostoronnij zv yazok yakij mozhe minyatis pid chas vikonannya programi Takim chinom odni ob yekti zalezhat vid inshih PrikladiC Priklad realizaciyi movoyu S include lt iostream gt include lt string gt using namespace std class Colleague class Mediator class ConcreteMediator class ConcreteColleague1 class ConcreteColleague2 struct Mediator virtual void Send string const amp message Colleague colleague const 0 class Colleague protected Mediator mediator public explicit Colleague Mediator mediator mediator mediator struct ConcreteColleague1 public Colleague explicit ConcreteColleague1 Mediator mediator Colleague mediator void Send string const amp message mediator gt Send message this void Notify string const amp message cout lt lt Colleague1 gets message lt lt message lt lt lt lt endl struct ConcreteColleague2 public Colleague explicit ConcreteColleague2 Mediator mediator Colleague mediator void Send string const amp message mediator gt Send message this void Notify string const amp message cout lt lt Colleague2 gets message lt lt message lt lt lt lt 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 string const amp message Colleague colleague const if colleague m Colleague1 m Colleague2 gt Notify message else if colleague m Colleague2 m Colleague1 gt Notify message void main ConcreteMediator m ConcreteColleague1 c1 amp m ConcreteColleague2 c2 amp m m SetColleague1 amp c1 m SetColleague2 amp c2 c1 Send How are you c2 Send Fine thanks C Priklad realizaciyi movoyu S using System using System Linq using System Collections Generic namespace MediatorPattern public interface IMediator void AddParticipant IParticipant participant void BroadcastMessage string message IParticipant sender public class ConcreteMediator IMediator private readonly ICollection lt IParticipant gt participants new List lt IParticipant gt public void AddParticipant IParticipant participant participants Add participant public void BroadcastMessage string message IParticipant sender foreach var participant in participants Where p gt p sender participant HandleMessage message public interface IParticipant void SendMessage string message void HandleMessage string message public class ConcreteParticipant IParticipant private readonly int id protected readonly IMediator mediator public ConcreteParticipant int id IMediator mediator id id mediator mediator public void SendMessage string message Console WriteLine Participant id send message message mediator BroadcastMessage message this public void HandleMessage string message Console WriteLine Participant id recieve message message class Program static void Main string args IMediator mediator new ConcreteMediator IParticipant participant1 new ConcreteParticipant 1 mediator IParticipant participant2 new ConcreteParticipant 2 mediator IParticipant participant3 new ConcreteParticipant 3 mediator mediator AddParticipant participant1 mediator AddParticipant participant2 mediator AddParticipant participant3 participant1 SendMessage Hello from first participant participant2 SendMessage Hello from second participant Priklad realizaciyi movoyu S using System using System Collections Generic namespace MediatorPattern public interface IMediator lt TEvent gt where TEvent EventArgs void AddHandler IParticipantHandler lt TEvent gt participant void BroadcastMessage TEvent eventArgs public class UserCreatedEventArgs EventArgs public string User get set public class UserMediator IMediator lt UserCreatedEventArgs gt private readonly ICollection lt IParticipantHandler lt UserCreatedEventArgs gt gt participants new List lt IParticipantHandler lt UserCreatedEventArgs gt gt public void AddHandler IParticipantHandler lt UserCreatedEventArgs gt participant participants Add participant public void BroadcastMessage UserCreatedEventArgs eventArgs foreach var participant in participants participant HandleEvent eventArgs public class ReportUpdatedEventArgs EventArgs public class ReportMediator IMediator lt ReportUpdatedEventArgs gt private readonly ICollection lt IParticipantHandler lt ReportUpdatedEventArgs gt gt participants new List lt IParticipantHandler lt ReportUpdatedEventArgs gt gt public void AddHandler IParticipantHandler lt ReportUpdatedEventArgs gt participant participants Add participant public void BroadcastMessage ReportUpdatedEventArgs eventArgs foreach var participant in participants participant HandleEvent eventArgs public interface IParticipantHandler lt T gt where T EventArgs void HandleEvent T message public interface IParticipantProducer lt T gt where T EventArgs void SendMessage T message public class DbParticipant IParticipantProducer lt UserCreatedEventArgs gt protected readonly IMediator lt UserCreatedEventArgs gt mediator public DbParticipant IMediator lt UserCreatedEventArgs gt mediator mediator mediator public void SendMessage UserCreatedEventArgs message mediator BroadcastMessage message public void AddUser string newUser SendMessage new UserCreatedEventArgs User newUser public class ReportBuilderParticipant IParticipantProducer lt ReportUpdatedEventArgs gt IParticipantHandler lt UserCreatedEventArgs gt protected readonly IMediator lt ReportUpdatedEventArgs gt mediator public ReportBuilderParticipant IMediator lt ReportUpdatedEventArgs gt mediator mediator mediator public void HandleEvent UserCreatedEventArgs message UpdateReport message private void UpdateReport UserCreatedEventArgs message Console WriteLine Report Add to report new user message User SendMessage new ReportUpdatedEventArgs public void SendMessage ReportUpdatedEventArgs message mediator BroadcastMessage message public class NotificationParticipant IParticipantHandler lt ReportUpdatedEventArgs gt IParticipantHandler lt UserCreatedEventArgs gt protected readonly IMediator lt ReportUpdatedEventArgs gt mediator public NotificationParticipant IMediator lt ReportUpdatedEventArgs gt mediator mediator mediator public void HandleEvent ReportUpdatedEventArgs message Console WriteLine Notification Report is updated and ready to download public void HandleEvent UserCreatedEventArgs message Console WriteLine Notification User message User joined chat class Program static void Main string args IMediator lt UserCreatedEventArgs gt userMediator new UserMediator IMediator lt ReportUpdatedEventArgs gt reportMediator new ReportMediator var db new DbParticipant userMediator var reportBuilder new ReportBuilderParticipant reportMediator var notificationSystem new NotificationParticipant reportMediator userMediator AddHandler reportBuilder userMediator AddHandler notificationSystem reportMediator AddHandler notificationSystem db AddUser John Doe Java Priklad realizaciyi movoyu Java import java awt Font import java awt event ActionEvent import java awt event ActionListener import javax swing JButton import javax swing JFrame import javax swing JLabel import javax swing JPanel Colleague interface interface Command void execute Abstract Mediator interface Mediator void book void view void search void registerView BtnView v void registerSearch BtnSearch s void registerBook BtnBook b void registerDisplay LblDisplay d Concrete mediator class ParticipantMediator implements Mediator BtnView btnView BtnSearch btnSearch BtnBook btnBook LblDisplay show public void registerView BtnView v btnView v public void registerSearch BtnSearch s btnSearch s public void registerBook BtnBook b btnBook b public void registerDisplay LblDisplay d show d public void book btnBook setEnabled false btnView setEnabled true btnSearch setEnabled true show setText booking public void view btnView setEnabled false btnSearch setEnabled true btnBook setEnabled true show setText viewing public void search btnSearch setEnabled false btnView setEnabled true btnBook setEnabled true show setText searching A concrete colleague class BtnView extends JButton implements Command Mediator med BtnView ActionListener al Mediator m super View addActionListener al med m med registerView this public void execute med view A concrete colleague class BtnSearch extends JButton implements Command Mediator med BtnSearch ActionListener al Mediator m super Search addActionListener al med m med registerSearch this public void execute med search A concrete colleague class BtnBook extends JButton implements Command Mediator med BtnBook ActionListener al Mediator m super Book addActionListener al med m med registerBook this public void execute med book class LblDisplay extends JLabel Mediator med LblDisplay Mediator m super Just start med m med registerDisplay this setFont new Font Arial Font BOLD 24 class MediatorDemo extends JFrame implements ActionListener Mediator med new ParticipantMediator MediatorDemo JPanel p new JPanel p add new BtnView this med p add new BtnBook this med p add new BtnSearch this med getContentPane add new LblDisplay med North getContentPane add p South setSize 400 200 setVisible true public void actionPerformed ActionEvent ae Command comd Command ae getSource comd execute public static void main String args new MediatorDemo Python Priklad realizaciyi movoyu Python Tipovij priklad poserednika zustrichayetsya u frejmvorku programnomu karkasi avtomatizovanogo testuvannya yakij skladayetsya z chotirtoh klasiv TC TestCategory TestManager Reporter DB Database import time class TC def init self self tm tm self bProblem 0 def setup self print Setting up the Test time sleep 1 self tm prepareReporting def execute self if not self bProblem print Executing the test time sleep 1 else print Problem in setup Test not executed def tearDown self if not self bProblem print Tearing down time sleep 1 self tm publishReport else print Test not executed No tear down required def setTM self TM self tm tm def setProblem self value self bProblem value class Reporter def init self self tm None def prepare self print Reporter Class is preparing to report the results time sleep 1 def report self print Reporting the results of Test time sleep 1 def setTM self TM self tm tm class DB def init self self tm None def insert self print Inserting the execution begin status in the Database time sleep 1 Following code is to simulate a communication from DB to TC import random if random randrange 1 4 3 return 1 def update self print Updating the test results in Database time sleep 1 def setTM self TM self tm tm class TestManager def init self self reporter None self db None self tc None def prepareReporting self rvalue self db insert if rvalue 1 self tc setProblem 1 self reporter prepare def setReporter self reporter self reporter reporter def setDB self db self db db def publishReport self self db update rvalue self reporter report def setTC self tc self tc tc if name main reporter Reporter db DB tm TestManager tm setReporter reporter tm setDB db reporter setTM tm db setTM tm For simplification we are looping on the same test Practically it could be about various unique test classes and their objects while 1 tc TC tc setTM tm tm setTC tc tc setup tc execute tc tearDown TypeScript Priklad realizaciyi movoyu TypeScript Injectable class EventMediator private customerChangedSubject new BehaviorSubject lt CustomerData gt null public customerChanged this customerChangedSubject asObservable public notifyOnCustomerChanged customerData CustomerData void this customerChangedSubject next customerData private productChangedSubject new BehaviorSubject lt ProductData gt null public productChanged this productChangedSubject asObservable public notifyOnProductChanged productData ProductData void this productChangedSubject next productData nadsilannya podij this eventMediator notifyOnCustomerChanged new CustomerData obrobka podij this eventMediator customerChanged subscribe c gt this customer c Priklad realizaciyi movoyu TypeScript Rishennya na osnovi integracijnoyi shini podij enum Events CustomerSelected class EmitEvent constructor public name Events value any Injectable class EventBus private subject new Subject lt any gt on event Events action any Subscription return this subject pipe filter e EmitEvent gt e name event map e EmitEvent gt e value subscribe action emit event EmitEvent void this subject next event nadsilannya podij this eventBus emit new EmitEvent Events CustomerSelected new CustomerData obrobka podij this eventBus on Events CustomerSelected c gt this customer c DzherelaDesign Patterns Elements of Reusable Object Oriented Software 9 listopada 2012 u Wayback Machine LiteraturaAlan Shallouej Dzhejms R Trott Shablony proektirovaniya Novyj podhod k obektno orientirovannomu analizu i proektirovaniyu Design Patterns Explained A New Perspective on Object Oriented Design M Vilyams 2002 288 s ISBN 0 201 71594 5