当前位置: 首页 > news >正文

实战设计模式之中介者模式

概述

        中介者模式是一种强大且灵活的设计模式,适用于需要优化对象间通信的场景。中介者模式通过引入一个中介对象,来封装一系列对象之间的交互。在没有中介者的情况下,这些对象之间可能会直接相互引用,导致系统中的类紧密耦合,难以维护和扩展。而通过使用中介者模式,可以将对象间的通信集中到一个中介者对象中,从而减少了对象之间的直接依赖,提高了系统的灵活性和可维护性。

        空中交通管制是现实生活中运用中介者模式的一个典型例子。在航空业中,空中交通管制系统扮演着中介者的角色。每架飞机就像是同事类,它们需要与其他飞机进行通信,以确保飞行的安全和效率。然而,如果让每架飞机都直接与其它所有飞机进行通信,不仅复杂度极高,而且容易引发混乱甚至危险。因此,空中交通管制员作为中介者,负责协调所有飞机的起飞、降落以及飞行路径,确保它们之间不会发生碰撞。在这个过程中,飞机只需遵循空中交通管制员的指示,而不需要知道其他飞机的具体情况。

基本原理

        中介者模式的核心思想是:通过引入一个中介对象,来封装一系列对象之间的交互,从而减少这些对象之间的直接依赖。在没有中介者的情况下,对象之间可能会形成复杂的网状结构,导致系统难以维护和扩展。中介者模式使得每个对象只需与中介者进行通信,而不需要知道其他对象的存在或操作方式,这大大降低了系统的耦合度,并提高了灵活性和可维护性。

        中介者模式主要由以下三个核心组件构成。

        1、抽象中介者。定义了同事类与中介者之间通信的接口,通常是一个接口或抽象类,具体实现留给子类完成。目的是为具体的中介者提供一个统一的接口,以便于同事类与中介者之间的交互。

        2、具体中介者。实现了抽象中介者的接口,包含了对同事类的引用,并负责处理同事类之间的交互逻辑。具体中介者了解所有同事类,并能够根据需要调用同事类的方法,或者通知其他同事类发生了某些事件。

        3、同事类。每个同事类都知道自己应该与中介者进行通信,但不知道也不关心其他同事类的存在或操作。同事类通常会持有对中介者的引用,并通过中介者发送消息给其他同事类。同事类只负责自身的业务逻辑,而不直接与其他同事类交互,所有的交互都通过中介者来进行。

        基于上面的核心组件,中介者模式的实现主要有以下四个步骤。

        1、定义抽象中介者。创建一个接口或抽象类,定义同事类与中介者之间通信的方法。这些方法通常是用于发送消息,或通知其他同事类发生的变化。

        2、创建具体中介者。实现抽象中介者接口,创建具体的中介者类。在具体中介者中,管理所有同事类的引用,并实现同事类之间交互的具体逻辑。确保具体中介者能够接收来自一个同事类的消息,并将消息转发给相关的同事类。

        3、定义同事类。创建同事类,它持有一个指向中介者的引用。同事类通过中介者发送消息给其他同事类,而不是直接与它们通信。同事类还应包含一些基本的行为和状态,以及处理接收到的消息的方法。

        4、集成同事类与中介者。将同事类注册到中介者中,使得中介者可以管理这些同事类。当同事类需要与其他同事类通信时,它通过中介者发送消息,而不是直接调用其他同事类的方法。

实战代码

        在下面的实战代码中,我们使用中介者模式模拟了空中交通管制的实现。

        首先,我们定义了抽象中介者接口CAirTrafficControl。它声明了注册飞机和更新位置的方法,为具体中介者提供了统一的操作接口。

        接着,通过CConcreteAirTrafficControl实现了这些方法,并添加了检查潜在碰撞的功能。在该类中,使用一个哈希表m_mapAircraft来存储所有已注册飞机的引用,另一个哈希表m_mapPosition记录每架飞机的位置坐标。每当有飞机更新其位置时,就会调用UpdatePosition方法。该方法不仅更新了飞机的位置信息,还会触发CheckForCollisions函数,以检查是否有任何两架飞机的距离小于预设的安全距离SAFE_DISTANCE。如果检测到可能的碰撞,AvoidCollision方法将被调用,通知相关飞机采取避让措施。

        然后,我们定义了同事类CAircraft。它代表系统中的各个飞机,并持有一个指向中介者的引用,可以通过中介者报告自己的当前位置。每个飞机实例都知道如何向空中交通控制中心报告其最新位置,并且当接收到碰撞警告时,会打印出相应的避让信息。

        最后,在main函数中,我们创建了一个具体的空中交通控制中心实例,并注册了两架飞机。通过调用UpdatePosition方法更新这两架飞机的位置,模拟它们的移动过程。随着飞机2逐渐靠近飞机1,最终触发了碰撞检测机制,导致两架飞机都收到了避让指令,以避免潜在的碰撞。

#include <iostream>
#include <unordered_map>
#include <string>
#include <cmath>using namespace std;class CAircraft;// 抽象中介者
class CAirTrafficControl
{
public:virtual void RegisterAircraft(const string& id, CAircraft* aircraft) = 0;virtual void UpdatePosition(const string& senderId, double x, double y) = 0;
};// 具体中介者:空中交通控制中心
class CConcreteAirTrafficControl : public CAirTrafficControl
{
public:void RegisterAircraft(const string& id, CAircraft* aircraft) override{m_mapAircraft[id] = aircraft;}void UpdatePosition(const string& senderId, double x, double y) override{m_mapPosition[senderId] = {x, y};CheckForCollisions(senderId);}void CheckForCollisions(const string &senderId);private:bool IsTooClose(double x1, double y1, double x2, double y2){return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)) < SAFE_DISTANCE;}private:struct Position{double x;double y;};unordered_map<string, CAircraft*> m_mapAircraft;unordered_map<string, Position> m_mapPosition;// 安全距离const double SAFE_DISTANCE = 10.0;
};// 同事类:飞机
class CAircraft
{
public:CAircraft(const string& id, CAirTrafficControl* atc) : m_id(id), m_pAtc(atc) {}string GetId() const { return m_id; }void UpdatePosition(double x, double y){cout << m_id << " updates pos to (" << x << ", " << y << ")" << endl;m_pAtc->UpdatePosition(m_id, x, y);}void AvoidCollision(const string& otherId){cout << GetId() << " taking action to avoid collision with " << otherId << endl;}private:string m_id;CAirTrafficControl* m_pAtc;
};void CConcreteAirTrafficControl::CheckForCollisions(const string& senderId)
{auto itSender = m_mapPosition.find(senderId);if (itSender == m_mapPosition.end()){return;}for (auto& it : m_mapPosition){if (it.first != senderId && IsTooClose(itSender->second.x, itSender->second.y, it.second.x, it.second.y)){cout << "Potential collision between " << senderId << " and " << it.first << endl;m_mapAircraft[it.first]->AvoidCollision(senderId);m_mapAircraft[senderId]->AvoidCollision(it.first);}}
}int main()
{CConcreteAirTrafficControl atc;CAircraft aircraft1("Flight 101", &atc);CAircraft aircraft2("Flight 202", &atc);atc.RegisterAircraft(aircraft1.GetId(), &aircraft1);atc.RegisterAircraft(aircraft2.GetId(), &aircraft2);// 飞机1更新位置aircraft1.UpdatePosition(100, 100);// 飞机2更新位置,接近飞机1aircraft2.UpdatePosition(150, 150);// 飞机2进一步靠近飞机1,触发碰撞警告aircraft2.UpdatePosition(105, 105);return 0;
}

总结

        在复杂的系统中,组件间的通信往往变得异常复杂。中介者模式提供了一种集中管理这些通信的方式,使得组件间的交互逻辑更加简洁明了。由于同事类之间的交互被集中在中介者中,因此当需要添加新的同事类或修改现有的交互逻辑时,只需要调整中介者的实现即可,而不会影响到其他同事类。这大大提高了系统的灵活性和可维护性,有助于快速响应需求变化。

        但如果系统中有大量同事类频繁地与中介者进行交互,那么中介者可能会成为性能瓶颈。特别是在高并发环境下,中介者的处理能力直接影响到整个系统的吞吐量和响应速度。因此,在设计中介者时,需要特别注意其性能表现,避免出现单点故障。

http://www.xdnf.cn/news/286273.html

相关文章:

  • 基于Boost库、Jsoncpp、cppjieba、cpp-httplib等构建Boost搜索引擎
  • Lua 元表和元方法
  • 重名导致does not name a type
  • 青少年编程与数学 02-018 C++数据结构与算法 25课题、图像处理算法
  • 科学养生,开启健康生活新篇章
  • [machine learning] Transformer - Attention (四)
  • ModBus协议详解:从基础概念到C#实现RTU与TCP通讯
  • Spring Boot 集成 Solr 的详细步骤及示例
  • C# WPF 布局
  • 算法笔记.约数个数
  • 基于muduo库实现高并发服务器
  • Nginx核心功能2
  • Linux:权限的理解
  • 健康养生:从生活点滴启航
  • 解决pycharm检测不到已经装好的conda的pytorch环境
  • 项目成本管理_挣得进度ES
  • 网络:cookie和session
  • 【硬核攻坚】告别CUDA OOM!DeepSeek部署显存瓶颈终极解决方案:三大策略高效落地
  • [特殊字符]Git 操作实战:如何将本地项目提交到远程 Gitee 仓库
  • RocketMQ与Kafka的区别
  • Nuxt3还能用吗?
  • 直方图反向投影
  • Three.js + React 实战系列 - 项目展示区开发详解 Projects 组件(3D 模型 + 动效 + 状态切换)✨
  • android-ndk开发(2): macOS 安装 ndk
  • PyTorch_自动微分模块
  • 时间同步服务核心知识笔记:原理、配置与故障排除
  • 因为gromacs必须安装cuda(系统自带的NVIDIA驱动不行),这里介绍下如何安装cuda
  • 学习路线(机器人软件架构)
  • Java常用注解大全(基于JDK17+SpringBoot3)
  • 对ubuntu的简单介绍