一、问题引出
使用 Mediator 模式简化对象间通信
在面向对象系统的设计和开发过程中,对象之间的交互和通信是最为常见的情况。当系统规模较小时,对象间的通信可以直接硬编码到各个对象的方法中。然而,随着系统规模的扩大,对象的数量增加,对象间的通信变得越来越复杂。这时,我们需要一种机制来简化对象间的通信,降低系统的复杂度。Mediator 模式正是为了解决这一问题而设计的。
Mediator 模式通过将对象间的交互和通信封装在一个中介者类中,使得各个对象不必显式地引用彼此,从而降低了系统的复杂性。此外,Mediator 模式还带来了系统对象间的松耦合,使得系统更易于维护和扩展。
二、Mediator 模式概述
Mediator 模式的核心思想是通过一个中介者对象来封装一组对象之间的交互。这样,对象之间不再直接通信,而是通过中介者进行间接通信。Mediator 模式的结构通常包括以下几个角色:
(1)Mediator(中介者):定义一个接口用于与各 Colleague 对象通信。
(2)ConcreteMediator(具体中介者):实现 Mediator 接口,协调各 Colleague 对象之间的交互。
(3)Colleague(同事类):每个 Colleague 对象都知道它的 Mediator 对象,并通过 Mediator 与其他 Colleague 对象通信。
通过这种方式,Mediator 模式将多对多的通信简化为一对多的通信,从而降低了系统的复杂性。
三、Mediator 模式的实现
代码实现
以下是 Mediator 模式的完整实现代码,采用 C++ 编写
Colleage.h
#ifndef _COLLEAGE_H_
#define _COLLEAGE_H_#include <string>
using namespace std;class Mediator;// Colleage 基类
class Colleage {
public:virtual ~Colleage();virtual void Action() = 0; // 执行操作virtual void SetState(const string& sdt) = 0; // 设置状态virtual string GetState() = 0; // 获取状态
protected:Colleage();Colleage(Mediator* mdt);Mediator* _mdt; // 中介者引用
};// 具体 ColleagueA 类
class ConcreteColleageA : public Colleage {
public:ConcreteColleageA();ConcreteColleageA(Mediator* mdt);~ConcreteColleageA();void Action();void SetState(const string& sdt);string GetState();
private:string _sdt; // 状态
};// 具体 ColleagueB 类
class ConcreteColleageB : public Colleage {
public:ConcreteColleageB();ConcreteColleageB(Mediator* mdt);~ConcreteColleageB();void Action();void SetState(const string& sdt);string GetState();
private:string _sdt; // 状态
};#endif //~_COLLEAGE_H_
Colleage.cpp
#include "Mediator.h"
#include "Colleage.h"
#include <iostream>
using namespace std;Colleage::Colleage() {}
Colleage::Colleage(Mediator* mdt) { this->_mdt = mdt; }
Colleage::~Colleage() {}// ConcreteColleageA 实现
ConcreteColleageA::ConcreteColleageA() {}
ConcreteColleageA::~ConcreteColleageA() {}
ConcreteColleageA::ConcreteColleageA(Mediator* mdt) : Colleage(mdt) {}
string ConcreteColleageA::GetState() { return _sdt; }
void ConcreteColleageA::SetState(const string& sdt) { _sdt = sdt; }
void ConcreteColleageA::Action() {_mdt->DoActionFromAtoB();cout << "State of ConcreteColleageB: " << this->GetState() << endl;
}// ConcreteColleageB 实现
ConcreteColleageB::ConcreteColleageB() {}
ConcreteColleageB::~ConcreteColleageB() {}
ConcreteColleageB::ConcreteColleageB(Mediator* mdt) : Colleage(mdt) {}
string ConcreteColleageB::GetState() { return _sdt; }
void ConcreteColleageB::SetState(const string& sdt) { _sdt = sdt; }
void ConcreteColleageB::Action() {_mdt->DoActionFromBtoA();cout << "State of ConcreteColleageB: " << this->GetState() << endl;
}
Mediator.h
#ifndef _MEDIATOR_H_
#define _MEDIATOR_H_class Colleage;// Mediator 基类
class Mediator {
public:virtual ~Mediator();virtual void DoActionFromAtoB() = 0; // 处理 A 到 B 的通信virtual void DoActionFromBtoA() = 0; // 处理 B 到 A 的通信
protected:Mediator();
};// 具体 Mediator 类
class ConcreteMediator : public Mediator {
public:ConcreteMediator();ConcreteMediator(Colleage* clgA, Colleage* clgB);~ConcreteMediator();void SetConcreteColleageA(Colleage* clgA);void SetConcreteColleageB(Colleage* clgB);Colleage* GetConcreteColleageA();Colleage* GetConcreteColleageB();void IntroColleage(Colleage* clgA, Colleage* clgB);void DoActionFromAtoB();void DoActionFromBtoA();
private:Colleage* _clgA; // Colleague A 引用Colleage* _clgB; // Colleague B 引用
};#endif //~_MEDIATOR_H_
Mediator.cpp
#include "Mediator.h"
#include "Colleage.h"Mediator::Mediator() {}
Mediator::~Mediator() {}// ConcreteMediator 实现
ConcreteMediator::ConcreteMediator() {}
ConcreteMediator::~ConcreteMediator() {}
ConcreteMediator::ConcreteMediator(Colleage* clgA, Colleage* clgB) {this->_clgA = clgA;this->_clgB = clgB;
}
void ConcreteMediator::DoActionFromAtoB() {_clgB->SetState(_clgA->GetState()); // 将 A 的状态传递给 B
}
void ConcreteMediator::SetConcreteColleageA(Colleage* clgA) { this->_clgA = clgA; }
void ConcreteMediator::SetConcreteColleageB(Colleage* clgB) { this->_clgB = clgB; }
Colleage* ConcreteMediator::GetConcreteColleageA() { return _clgA; }
Colleage* ConcreteMediator::GetConcreteColleageB() { return _clgB; }
void ConcreteMediator::IntroColleage(Colleage* clgA, Colleage* clgB) {this->_clgA = clgA;this->_clgB = clgB;
}
void ConcreteMediator::DoActionFromBtoA() {_clgA->SetState(_clgB->GetState()); // 将 B 的状态传递给 A
}
main.cpp
#include "Mediator.h"
#include "Colleage.h"
#include <iostream>
using namespace std;int main(int argc, char* argv[]) {ConcreteMediator* m = new ConcreteMediator();ConcreteColleageA* c1 = new ConcreteColleageA(m);ConcreteColleageB* c2 = new ConcreteColleageB(m);m->IntroColleage(c1, c2);c1->SetState("old");c2->SetState("old");c1->Action();c2->Action();cout << endl;c1->SetState("new");c1->Action();c2->Action();cout << endl;c2->SetState("old");c2->Action();c1->Action();return 0;
}
代码说明
(1)Colleage 类:
Colleage 是抽象基类,定义了同事类的接口。
ConcreteColleageA 和 ConcreteColleageB 是具体的同事类,通过中介者与其他同事类通信。
(2)Mediator 类:
Mediator 是抽象基类,定义了中介者的接口。
ConcreteMediator 是具体的中介者类,负责协调同事类之间的通信。
(3)通信流程:
当 ConcreteColleageA 调用 Action 方法时,它会通过中介者 ConcreteMediator 与 ConcreteColleageB 通信。
同样,当 ConcreteColleageB 调用 Action 方法时,它会通过中介者与 ConcreteColleageA 通信。
(4)松耦合:
同事类之间没有直接依赖,所有通信都通过中介者进行。
这种设计使得系统更易于维护和扩展。
运行结果
(1)初始状态下,`ConcreteColleageA` 和 `ConcreteColleageB` 的状态均为 `"old"`。
(2)当 `ConcreteColleageA` 的状态变为 `"new"` 时,`ConcreteColleageB` 的状态也会通过中介者变为 `"new"`。
(3)当 `ConcreteColleageB` 的状态变为 `"old"` 时,`ConcreteColleageA` 的状态也会通过中介者变为 `"old"`。
通过这种方式,`ConcreteColleageA` 和 `ConcreteColleageB` 之间的通信完全由中介者处理,它们彼此之间没有直接的依赖关系。
四、总结讨论
Mediator 模式通过将对象间的通信封装到一个中介者类中,简化了系统的复杂性。它还将多对多的通信转化为一对多的通信,降低了系统的耦合性。此外,Mediator 模式使得系统的控制更加集中,符合面向对象设计中单一职责的原则。
Mediator 模式是一种非常有用的设计模式,特别适用于对象间通信复杂的系统。通过使用 Mediator 模式,我们可以将对象间的通信逻辑集中到一个中介者类中,从而降低系统的复杂性和耦合性。在实际开发中,Mediator 模式可以与其他设计模式(如 Observer 模式)结合使用,以实现更强大的功能。