Паттерн Посредник на C++
Посредник – это поведенческий паттерн, который упрощает коммуникацию между компонентами системы.
Посредник убирает прямые связи между отдельными компонентами, заставляя их общаться друг с другом через себя.
Особенности паттерна на C++
Сложность:
Популярность:
Применимость: Пожалуй, самое популярное применение Посредника в C++ коде – это связь нескольких компонентов GUI одной программы.
Концептуальный пример
Этот пример показывает структуру паттерна Посредник, а именно – из каких классов он состоит, какие роли эти классы выполняют и как они взаимодействуют друг с другом.
main.cc: Пример структуры паттерна
#include <iostream>
#include <string>
/**
* Интерфейс Посредника предоставляет метод, используемый компонентами для
* уведомления посредника о различных событиях. Посредник может реагировать на
* эти события и передавать исполнение другим компонентам.
*/
class BaseComponent;
class Mediator {
public:
virtual void Notify(BaseComponent *sender, std::string event) const = 0;
};
/**
* Базовый Компонент обеспечивает базовую функциональность хранения экземпляра
* посредника внутри объектов компонентов.
*/
class BaseComponent {
protected:
Mediator *mediator_;
public:
BaseComponent(Mediator *mediator = nullptr) : mediator_(mediator) {
}
void set_mediator(Mediator *mediator) {
this->mediator_ = mediator;
}
};
/**
* Конкретные Компоненты реализуют различную функциональность. Они не зависят от
* других компонентов. Они также не зависят от каких-либо конкретных классов
* посредников.
*/
class Component1 : public BaseComponent {
public:
void DoA() {
std::cout << "Component 1 does A.\n";
this->mediator_->Notify(this, "A");
}
void DoB() {
std::cout << "Component 1 does B.\n";
this->mediator_->Notify(this, "B");
}
};
class Component2 : public BaseComponent {
public:
void DoC() {
std::cout << "Component 2 does C.\n";
this->mediator_->Notify(this, "C");
}
void DoD() {
std::cout << "Component 2 does D.\n";
this->mediator_->Notify(this, "D");
}
};
/**
* Конкретные Посредники реализуют совместное поведение, координируя отдельные
* компоненты.
*/
class ConcreteMediator : public Mediator {
private:
Component1 *component1_;
Component2 *component2_;
public:
ConcreteMediator(Component1 *c1, Component2 *c2) : component1_(c1), component2_(c2) {
this->component1_->set_mediator(this);
this->component2_->set_mediator(this);
}
void Notify(BaseComponent *sender, std::string event) const override {
if (event == "A") {
std::cout << "Mediator reacts on A and triggers following operations:\n";
this->component2_->DoC();
}
if (event == "D") {
std::cout << "Mediator reacts on D and triggers following operations:\n";
this->component1_->DoB();
this->component2_->DoC();
}
}
};
/**
* Клиентский код.
*/
void ClientCode() {
Component1 *c1 = new Component1;
Component2 *c2 = new Component2;
ConcreteMediator *mediator = new ConcreteMediator(c1, c2);
std::cout << "Client triggers operation A.\n";
c1->DoA();
std::cout << "\n";
std::cout << "Client triggers operation D.\n";
c2->DoD();
delete c1;
delete c2;
delete mediator;
}
int main() {
ClientCode();
return 0;
}
Output.txt: Результат выполнения
Client triggers operation A.
Component 1 does A.
Mediator reacts on A and triggers following operations:
Component 2 does C.
Client triggers operation D.
Component 2 does D.
Mediator reacts on D and triggers following operations:
Component 1 does B.
Component 2 does C.