设计模式(4)--对象行为(5)--中介者

1. 意图

    用一个中介对象来封装一系列的对象交互。

    中介者使各对象不需要显式地相互引用,从而使其耦合松散,

    而且可以独立地改变它们之间的交互。

2. 四种角色

    抽象中介者(Mediator)、具体中介者(Concrete Mediator)、抽象同事(Colleague)、

    具体同事(Concrete Colleague)

3. 优点

    3.1 减少了子类生成。

    3.2 将各个Colleague解耦。

    3.3 简化了对象协议。

    3.4 对对象如何协作进行了抽象。

4. 缺点

    4.1 使控制集中化,可能使中介者自身称为一个难于维护的庞然大物

5. 相关模式

    5.1 Mediator的协议是多向的,提供了Colleague对象间的协作行为;
          而Façade的协议是单向的,只能Façade对子系统提出请求。

    5.2 Colleague可使用Observer模式与Mediator通信。

6. 代码示意(C++)
#pragma once
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Colleague;

class Mediator
{
public:
	virtual void SendMessage(const string& message, Colleague* pFrom) = 0;
	virtual void AddColleague(Colleague* pColleague) = 0;
};

class ConcreteMediator :public Mediator
{
	vector<Colleague*> m_colleagues;
public:
	virtual void SendMessage(const string& message, Colleague* pFrom);
	virtual void AddColleague(Colleague* pColleague);
};

class Colleague
{
	string m_strName;
	Mediator* m_pMediator;
public:
	Colleague(Mediator* pMediator, const string& strName) {
		m_pMediator = pMediator;
		m_strName = strName;
	}
	void SendMessage(const string& message) {
		m_pMediator->SendMessage(message, this);
	}
	string GetName() { return m_strName; }

	virtual void GetMessage(const string& message, const string& name) = 0;
};

class ConcreteColleage1 :public Colleague
{
public:
	ConcreteColleage1(Mediator* pMediator) :Colleague(pMediator, "ConcreteColleage1") {

	}
	virtual void GetMessage(const string& message, const string& name) {
		cout << "ConcreteColleage1 got message:" << message << ",from:" << name << endl;
	}
};

class ConcreteColleage2 :public Colleague
{
public:
	ConcreteColleage2(Mediator* pMediator) :Colleague(pMediator, "ConcreteColleage2") {

	}
	virtual void GetMessage(const string& message, const string& name) {
		cout << "ConcreteColleage2 got message:" << message << ",from:" << name << endl;
	}
};

 Mediator.cpp:

#include "Mediator.h"

void ConcreteMediator::SendMessage(const string& message, Colleague* pFrom) {
	auto it = m_colleagues.begin();
	while (it != m_colleagues.end()) {
		if (pFrom != (*it)) {
			(*it)->GetMessage(message, pFrom->GetName());
		}
		++it;
	}
}
void ConcreteMediator::AddColleague(Colleague* pColleague) {
	m_colleagues.emplace_back(pColleague);
}
#include "Mediator.h"
int main() {
	Mediator* pMediator = new ConcreteMediator();

	Colleague* pColleague1 = new ConcreteColleage1(pMediator);
	Colleague* pColleague2 = new ConcreteColleage2(pMediator);
	pMediator->AddColleague(pColleague1);
	pMediator->AddColleague(pColleague2);

	pColleague1->SendMessage("hello");

	pColleague2->SendMessage("hi");

	delete pColleague1;
	delete pColleague2;
	delete pMediator;
	return 0;
}

运行结果:

 6.1 ConcreteColleage之间不直接打交道,消息通过ConcreteMediator传递(3.2)。

 6.2 将多对多的关系变成了一对多(一个中介对多个同事)的关系(3.3)。

相关推荐

  1. 行为设计模式中介模式

    2023-12-27 06:54:03       57 阅读
  2. 设计模式行为设计模式——中介模式

    2023-12-27 06:54:03       44 阅读
  3. 设计模式行为模式中介模式

    2023-12-27 06:54:03       46 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-27 06:54:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-27 06:54:03       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-27 06:54:03       82 阅读
  4. Python语言-面向对象

    2023-12-27 06:54:03       91 阅读

热门阅读

  1. SimLM: Can Language Models Infer Parameters of Physical Systems?

    2023-12-27 06:54:03       53 阅读
  2. Go语言Web框架Gin常见用法

    2023-12-27 06:54:03       47 阅读
  3. gin实现登录逻辑,包含cookie,session

    2023-12-27 06:54:03       48 阅读
  4. 手写一个vuex?

    2023-12-27 06:54:03       56 阅读
  5. 【Springboot】解决 MacOS M1 上 Netty 的 DNS 解析错误

    2023-12-27 06:54:03       63 阅读