当前位置: 首页 > 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;
}

总结

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

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

相关文章:

  • archlinux安装waydroid
  • 利用jQuery 实现多选标签下拉框,提升表单交互体验
  • Scrapy爬虫实战:如何用Rules实现高效数据采集
  • 拷贝多个Excel单元格区域为图片并粘贴到Word
  • 破晓之啼:子安的语言奇迹与生命沉思
  • 一款基于 .NET 开源的多功能的 B 站视频下载工具
  • 基于 HTML5 Canvas 实现图片旋转与下载功能
  • 交换机工作原理(MAC地址表、VLAN)
  • BC9 printf的返回值
  • 《进制转换的终极指南:原理、方法与编程应用》
  • Kotlin-空值和空类型
  • FastMCP - 官方文档翻译
  • 《Spring 中 @Autowired 注解详解》
  • Manus AI: 冲破次元壁,让手写文字跨越语言鸿沟
  • 深度学习入门(五):学习相关的技巧
  • 蓝桥杯 18. 积木
  • 基于yolov11的打电话玩手机检测系统python源码+pytorch模型+评估指标曲线+精美GUI界面
  • 防止交叉验证中的数据泄露:提升模型在实际环境中的性能
  • React状态管理
  • 攻防世界-php伪协议和文件包含
  • 吴清:巴菲特即将退休,但价值投资、长期投资、理性投资、努力回报投资者等理念不会退休
  • 广东省联社:积极推动改制组建农商联合银行工作
  • 洗衣机无法有效杀菌
  • 特朗普:对所有在国外制作进入美国的电影征收100%关税
  • 专访|刘伟强:在《水饺皇后》里,我放进儿时全家福照片
  • 马上评|“景区陪爬”能成为新职业吗?