基于C++的《Head First设计模式》笔记——中介者模式

目录

一.专栏介绍

二.中介者模式概念

三.案例与代码

四.中介者模式的优点

五.中介者模式的缺点

六.中介者模式的用途

七.总结


一.专栏介绍

本专栏是我学习《head first》设计模式的笔记。这本书中是用Java语言为基础的,我将用C++语言重写一遍,并且详细讲述其中的设计模式,涉及是什么,为什么,怎么做,自己的心得等等。希望阅读者在读完我的这个专题后,也能在开发中灵活且正确的使用,或者在面对面试官时,能够自信地说自己熟悉常用设计模式。

本章将开始**中介者模式(Mediator Pattern)**的学习。

二.中介者模式概念

使用中介者模式来集中相关对象之间复杂的沟通和控制方式。

用一个中介者对象封装一系列对象之间的交互逻辑,让原本相互依赖、直接通信的对象解耦,所有对象只和中介者通信,不再直接引用彼此

当多个对象之间存在复杂的网状依赖关系 时(比如 A 调用 B、B 调用 C、C 调用 A),代码会变得难以维护、修改和扩展。中介者模式把网状结构 变成星型结构所有对象只对接中介者,中介者统一调度交互。中介者就是那颗星星

网状图:

星状图:

核心角色:

  1. 抽象中介者(Mediator):定义统一的交互接口,声明对象之间通信的方法;

  2. 具体中介者(ConcreteMediator):实现抽象中介者,持有所有交互对象的引用,处理具体的交互逻辑;

  3. 抽象同事类(Colleague):定义公共方法,持有中介者的引用;

  4. 具体同事类(ConcreteColleague):实现自身业务逻辑,需要交互时,通过中介者通知其他对象。

三.案例与代码

我们实现一个多人聊天室的demo,当聊天室里的用户发送消息时,其他人都会收到。这里的用户就是中介者模式的同事类对象,他们通过中介者类将消息发送给其他人。

代码如下:

mediatorPattern.h:

cpp 复制代码
#pragma once
#include <string>
#include <vector>
#include <iostream>
using namespace std;

class User;

// 中介者抽象类
class Mediator
{
public:
	virtual ~Mediator() = default;
	// 依靠User引用将消息发送给User
	virtual void send(const string& message, User* sender) = 0;
	// 添加User引用
	virtual void addUser(User* nUser) = 0;
};

class User
{
public:
	User(Mediator* m, string n):
		mediator(m), name(n)
	{}
	virtual ~User() = default;
	// 向其他人发送消息,用中介者引用来发送
	virtual void send(const string& message) = 0;
	// 提供给中介者使用,中介者用这个函数将消息发送给自己
	virtual void receive(const string& message) = 0;
protected:
	Mediator* mediator;			// 中介者引用
	string name;				// 用户姓名
};

// 中介者具体类
class ConcreteMediator : public Mediator
{
public:
	void send(const string& message, User* sender) override
	{
		for (const auto& user : users)
		{
			// 不发送给自己(不回显)
			if (user != sender) user->receive(message);
		}
	}
	void addUser(User* nUser)
	{
		users.push_back(nUser);
	}
private:
	vector<User*> users;				// 子类自定义数据结构和提供添加等方法,更灵活
};

class ConcreteUser : public User
{
public:
	ConcreteUser(Mediator* m, string n):
		User(m, n)
	{}
	virtual ~ConcreteUser() = default;
	void send(const string& message) override
	{
		mediator->send(message, this);
	}
	void receive(const string& message)
	{
		cout << name << "收到消息:" << message << endl;
	}
};

代码说明:

  • 这里的用户类是中介者模式概念里的同事类。
  • 用户类和中介者类持有彼此的引用。
  • 中介者类管理用户的数据结构(比如这里的vector)交由具体中介者类定义并实现addUser()虚函数,这样更灵活。
  • 用户类send()方法调用中介者引用的send()方法,仅与中介者"这颗星星"交互,中介者再调用各个用户类的引用的receive()方法让他们接收。

main.cpp:

cpp 复制代码
#include "mediatorPattern.h"

int main()
{
	Mediator* mediator = new ConcreteMediator();

	User* Bob = new ConcreteUser(mediator, "Bob");
	User* Mike = new ConcreteUser(mediator, "Mike");
	User* John = new ConcreteUser(mediator, "John");

	mediator->addUser(Bob);
	mediator->addUser(Mike);
	mediator->addUser(John);

	Bob->send("Hello everyone!");
	cout << endl;
	Mike->send("How do you guys think?");
	cout << endl;
	John->send("Good morning!");

	delete mediator;
	delete Bob;
	delete Mike;
	delete John;

	return 0;
}

运行输出:

每个用户发送的消息都被其他用户收到了!

四.中介者模式的优点

  • 通过将中介者支持的对象从系统解耦,增加了对象的复用性。附和单一职责原则。

  • 通过将控制逻辑集中,简化了系统的维护。集中管理交互规则,修改逻辑只需修改中介者 。附和开闭原则

五.中介者模式的缺点

  • 中介者模式的一个缺点是,如果设计不当,中介者对象本身会变得过度复杂。

六.中介者模式的用途

  • 多个对象之间存在复杂的相互调用(如GUI组件、聊天室、调度系统)。
  • 想要简化对象之间的依赖关系,提高代码可维护性。
  • 需要集中控制一组对象的交互行为。

七.中介者模式 vs 观察者模式

观察者模式 == 老师上课

老师(主题)一说话,所有学生(观察者)都听到。一对多、自动广播、不需要中间转发。

中介者模式 == 聊天室

所有人(用户)不直接对话,都发给聊天室(中介者),中介者转发。多对多、互相不认识、完全靠中介调度。

八.总结

  • 中介者模式核心:解耦网状依赖,转为星型交互,统一调度

  • 核心角色:抽象中介者、具体中介者、抽象同事、具体同事;

  • 核心逻辑:对象不直接通信,全部通过中介者转发 / 调度。

相关推荐
路小雨~2 小时前
Django 学习笔记:从入门到项目开发的完整梳理
笔记·python·学习·django
chushiyunen2 小时前
langchain笔记、实现rag笔记
笔记·langchain
路小雨~2 小时前
微服务全体系学习笔记(从入门到落地)
笔记·微服务
鄭郑2 小时前
Figma学习笔记---03
笔记·学习·figma
程序员小寒2 小时前
JavaScript设计模式(四):发布-订阅模式实现与应用
开发语言·前端·javascript·设计模式
Heartache boy2 小时前
野火STM32_HAL库版课程笔记-空气、烟雾传感器公式换算
笔记·stm32·嵌入式硬件
m0_651562523 小时前
2026/3/26 学习笔记——终端复用工具screen
笔记·学习
sinat_255487813 小时前
JSON·学习笔记
java·开发语言·笔记·算法