Посредник (Mediator) — различия между версиями
Материал из Вики ИТ мехмата ЮФУ
Admin (обсуждение | вклад) |
Admin (обсуждение | вклад) (→Участники) |
||
(не показаны 23 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
[[Страница_курса_Паттерны_проектирования| К основной странице курса]] | [[Страница_курса_Паттерны_проектирования| К основной странице курса]] | ||
− | + | __NOTOC__ | |
− | + | === Описание === | |
В большой системе с множеством объектов каждый объект может передавать сообщения другому. В результате этого сильно возрастает количество связей между объектами (n^2). | В большой системе с множеством объектов каждый объект может передавать сообщения другому. В результате этого сильно возрастает количество связей между объектами (n^2). | ||
Вместо этого предлагается завести объект-посредник, через который передавать эти сообщения (n связей) | Вместо этого предлагается завести объект-посредник, через который передавать эти сообщения (n связей) | ||
− | + | === Пример === | |
При выборе поля списка меняется поле ввода | При выборе поля списка меняется поле ввода | ||
− | [[Изображение:MediatorExample.png| | + | ====Участники==== |
+ | * Widget и его наследники - взаимодействующие через посредника объекты | ||
+ | * FontDialogDirector - '''посредник''' | ||
+ | |||
+ | ==== Диаграмма классов для примера ==== | ||
+ | [[Изображение:MediatorExample.png|600px]] | ||
+ | |||
+ | Как работает: | ||
+ | * Изменившийся ListBox вызывает Changed(), который вызывает FontDialogDirector.WidgetChanged(). | ||
+ | * FontDialogDirector.WidgetChanged вызывает GetSelection() для объекта ListBox и затем SetText для связанного объекта TextField | ||
+ | |||
+ | ==== Диаграмма последовательности для примера ==== | ||
+ | [[Изображение:MediatorExampleSeq.png]] | ||
+ | |||
+ | === Общая диаграмма классов для паттерна Посредник === | ||
+ | [[Изображение:MediatorCommon.png|600px]] | ||
+ | ==== Участники==== | ||
+ | |||
+ | * '''Mediator''' - посредник. Определяет интерфейс для обмена информацией с объектами Colleague | ||
+ | * '''ConcreteMediator'''. Владеет информацией о всех объектах Colleague, координирует их действие | ||
+ | * '''Colleague'''. Каждый объект Colleague знает о своем объекте Mediator. Все объекты Colleague обмениваются информацией только с посредником | ||
+ | |||
+ | === Код === | ||
+ | <source lang="Csharp"> | ||
+ | class MainApp { | ||
+ | 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"); | ||
+ | } | ||
+ | } | ||
+ | abstract class Mediator { | ||
+ | public abstract void Send(string message, Colleague colleague); | ||
+ | } | ||
+ | class ConcreteMediator : Mediator { | ||
+ | ConcreteColleague1 colleague1; | ||
+ | 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); | ||
+ | } | ||
+ | } | ||
+ | abstract class Colleague | ||
+ | { | ||
+ | protected Mediator mediator; | ||
+ | |||
+ | public Colleague(Mediator mediator) | ||
+ | { this.mediator = mediator; } | ||
+ | } | ||
+ | |||
+ | class ConcreteColleague1 : Colleague { | ||
+ | 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); } | ||
+ | } | ||
+ | class ConcreteColleague2 : Colleague ... | ||
+ | </source> | ||
+ | |||
+ | === Достоинства === | ||
+ | * Устраняет связанность между коллегами | ||
+ | * Выделяет механизм взаимодействия объектов в отдельную сущность | ||
+ | === Недостатки === | ||
+ | * Централизует управление. Посредник становится монолитом, который трудно сопровождать |
Текущая версия на 10:41, 11 ноября 2014
Описание
В большой системе с множеством объектов каждый объект может передавать сообщения другому. В результате этого сильно возрастает количество связей между объектами (n^2).
Вместо этого предлагается завести объект-посредник, через который передавать эти сообщения (n связей)
Пример
При выборе поля списка меняется поле ввода
Участники
- Widget и его наследники - взаимодействующие через посредника объекты
- FontDialogDirector - посредник
Диаграмма классов для примера
Как работает:
- Изменившийся ListBox вызывает Changed(), который вызывает FontDialogDirector.WidgetChanged().
- FontDialogDirector.WidgetChanged вызывает GetSelection() для объекта ListBox и затем SetText для связанного объекта TextField
Диаграмма последовательности для примера
Общая диаграмма классов для паттерна Посредник
Участники
- Mediator - посредник. Определяет интерфейс для обмена информацией с объектами Colleague
- ConcreteMediator. Владеет информацией о всех объектах Colleague, координирует их действие
- Colleague. Каждый объект Colleague знает о своем объекте Mediator. Все объекты Colleague обмениваются информацией только с посредником
Код
class MainApp {
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");
}
}
abstract class Mediator {
public abstract void Send(string message, Colleague colleague);
}
class ConcreteMediator : Mediator {
ConcreteColleague1 colleague1;
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);
}
}
abstract class Colleague
{
protected Mediator mediator;
public Colleague(Mediator mediator)
{ this.mediator = mediator; }
}
class ConcreteColleague1 : Colleague {
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); }
}
class ConcreteColleague2 : Colleague ...
Достоинства
- Устраняет связанность между коллегами
- Выделяет механизм взаимодействия объектов в отдельную сущность
Недостатки
- Централизует управление. Посредник становится монолитом, который трудно сопровождать