Посредник (шаблон проектирования)
Посредник (англ. Mediator) — поведенческий шаблон проектирования, обеспечивающий взаимодействие множества объектов, формируя при этом слабое зацепление и избавляя объекты от необходимости явно ссылаться друг на друга. ПроблемаОбеспечить взаимодействие множества объектов, сформировав при этом слабую связанность и избавив объекты от необходимости явно ссылаться друг на друга. РешениеСоздать объект, инкапсулирующий способ взаимодействия множества объектов. ПреимуществаУстраняется связанность между "Коллегами", централизуется управление. Структура
Описание"Посредник" определяет интерфейс для обмена информацией с объектами "Коллеги", "Конкретный посредник" координирует действия объектов "Коллеги". Каждый класс "Коллеги" знает о своем объекте "Посредник", все "Коллеги" обмениваются информацией только с посредником, при его отсутствии им пришлось бы обмениваться информацией напрямую. "Коллеги" посылают запросы посреднику и получают запросы от него. "Посредник" реализует кооперативное поведение, пересылая каждый запрос одному или нескольким "Коллегам". ПримерыПример на JavaИсходный текст на Java public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public void send(String message) {
mediator.send(message, this);
}
public abstract void notify(String message);
}
public abstract class Mediator {
public abstract void send(String message, Colleague sender);
}
public class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
@Override
public void notify(String message) {
System.out.println("Colleague1 gets message: " + message);
}
}
public class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
@Override
public void notify(String message) {
System.out.println("Colleague2 gets message: " + message);
}
}
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 sender) {
if (sender.equals(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
/// </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
{
public ConcreteColleague1 Colleague1 { private get; set; }
public ConcreteColleague2 Colleague2 { private get; set; }
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>
#include <string>
class Colleague;
class Mediator;
class ConcreteMediator;
class ConcreteColleague1;
class ConcreteColleague2;
class Mediator
{
public:
virtual void Send(std::string const& message, Colleague *colleague) const = 0;
};
class Colleague
{
protected:
Mediator* mediator_;
public:
explicit Colleague(Mediator *mediator):mediator_(mediator)
{
}
};
class ConcreteColleague1:public Colleague
{
public:
explicit ConcreteColleague1(Mediator* mediator):Colleague(mediator)
{
}
void Send(std::string const& message)
{
mediator_->Send(message, this);
}
void Notify(std::string const& message)
{
std::cout << "Colleague1 gets message '" << message << "'" << std::endl;
}
};
class ConcreteColleague2:public Colleague
{
public:
explicit ConcreteColleague2(Mediator *mediator):Colleague(mediator)
{
}
void Send(std::string const& message)
{
mediator_->Send(message, this);
}
void Notify(std::string const& message)
{
std::cout << "Colleague2 gets message '" << message << "'" << 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 const& message, Colleague *colleague) const
{
if (colleague==m_Colleague1)
{
m_Colleague2->Notify(message);
}
else if (colleague==m_Colleague2)
{
m_Colleague1->Notify(message);
}
}
};
int main()
{
ConcreteMediator m;
ConcreteColleague1 c1(&m);
ConcreteColleague2 c2(&m);
m.SetColleague1(&c1);
m.SetColleague2(&c2);
c1.Send("How are you?");
c2.Send("Fine, thanks");
std::cin.get();
return 0;
}
Output
Colleague2 gets message 'How are you?'
Colleague1 gets message 'Fine, thanks'
Пример на PythonИсходный текст на Python from abc import ABCMeta, abstractmethod
from weakref import proxy
import inspect
class Mediator(metaclass=ABCMeta):
"""
Абстрактный канал общения между коллегами
"""
@abstractmethod
def send(self, message: str) -> None:
"""
Отправка сообщения между коллегами
"""
pass
class Colleague(metaclass=ABCMeta):
"""
Абстрактный работник, который не против пообщаться со своими коллегами
"""
def __init__(self, mediator: Mediator) -> None:
"""
Constructor.
:param mediator: канал общения с коллегами
"""
self._mediator = proxy(mediator)
@abstractmethod
def send(self, message: str) -> None:
"""
Отправка сообщения через канал общения
"""
pass
@abstractmethod
def receive(self, message: str) -> None:
"""
Получения сообщения через канал общения
"""
pass
class SkypeBetweenTwoColleagues(Mediator):
"""
Канал в скайпе для общения между двумя людьми
"""
def __init__(self) -> None:
"""
Constructor.
"""
self._first = None
self._second = None
def set_first(self, first: Colleague) -> None:
"""
Привязывает к каналу первого участника разговора
"""
self._first = first
def set_second(self, second: Colleague) -> None:
"""
Привязывает к каналу второго участника разговора
"""
self._second = second
def send(self, message: str) -> None:
sender = inspect.currentframe().f_back.f_locals['self']
receiver = self._first if sender == self._second else self._second
receiver.receive(message)
class Bill(Colleague):
def send(self, message: str) -> None:
self._mediator.send(message)
def receive(self, message: str) -> None:
print('Билл получил сообщение: {}'.format(message))
class Steve(Colleague):
def send(self, message: str) -> None:
self._mediator.send(message)
def receive(self, message: str) -> None:
print('Стив прочитал в скайпе сообщение: {}'.format(message))
if __name__ == '__main__':
print('OUTPUT:')
skype = SkypeBetweenTwoColleagues()
bill = Bill(skype)
steve = Steve(skype)
skype.set_first(bill)
skype.set_second(steve)
bill.send('Начинай работать, бездельник!')
steve.send('Нет')
'''
OUTPUT:
Стив прочитал в скайпе сообщение: Начинай работать, бездельник!
Билл получил сообщение: Нет
'''
Пример на DelphiИсходный текст на языке Delphi program MediatorExample;
{$APPTYPE CONSOLE}
type
IColleague = interface
procedure Send(AMessage: string);
procedure Notify(AMessage: string);
end;
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;
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.
Ссылки
|
Portal di Ensiklopedia Dunia