Посредник (Mediator) — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Участники)
 
Строка 29: Строка 29:
 
* '''ConcreteMediator'''. Владеет информацией о всех объектах Colleague, координирует их действие
 
* '''ConcreteMediator'''. Владеет информацией о всех объектах Colleague, координирует их действие
 
* '''Colleague'''. Каждый объект Colleague знает о своем объекте Mediator. Все объекты 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 - посредник

Диаграмма классов для примера

MediatorExample.png

Как работает:

  • Изменившийся ListBox вызывает Changed(), который вызывает FontDialogDirector.WidgetChanged().
  • FontDialogDirector.WidgetChanged вызывает GetSelection() для объекта ListBox и затем SetText для связанного объекта TextField

Диаграмма последовательности для примера

MediatorExampleSeq.png

Общая диаграмма классов для паттерна Посредник

MediatorCommon.png

Участники

  • 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 ...

Достоинства

  • Устраняет связанность между коллегами
  • Выделяет механизм взаимодействия объектов в отдельную сущность

Недостатки

  • Централизует управление. Посредник становится монолитом, который трудно сопровождать