漫谈设计模式 [16]:中介者模式

news2024/9/17 0:07:59

引导性开场

菜鸟:老鸟,我最近在开发一个聊天应用的时候遇到了点问题。每个用户都需要与其他用户直接通信,这让我在代码中写了很多复杂的逻辑来管理这些联系。这样下去,代码越来越难维护了。你有什么建议吗?

老鸟:嗯,这确实是个常见的问题。你有没有听说过中介者模式?

菜鸟:中介者模式?没听过。它能解决我现在的问题吗?

老鸟:绝对可以。让我给你详细解释一下。

渐进式介绍概念

老鸟:我们可以用一个简单的生活例子来理解中介者模式。想象一下,你在一个公司工作,公司里有很多同事。如果每个同事都需要直接和其他所有同事沟通,整个沟通过程会非常混乱,对吧?

菜鸟:对啊,人越多越难管理。

老鸟:所以,公司通常会有一个中介——比如一个经理。所有的沟通都通过经理来进行。同事A想和同事B沟通,他只需要告诉经理,经理再去通知同事B。这样,沟通就变得简单和有序了。这就是中介者模式的核心思想。

菜鸟:哦,我明白了。中介者模式是通过一个中介来简化对象之间的通信。

Python代码示例,逐步展开

老鸟:让我们通过一个简单的 Python 示例来进一步理解吧。

基础实现

老鸟:首先,我们来看看没有中介者模式的实现。假设我们有两个用户,每个用户都可以直接向另一个用户发送消息。

class User:
    def __init__(self, name):
        self.name = name
        self.contacts = []

    def add_contact(self, user):
        self.contacts.append(user)

    def send_message(self, message, to_user):
        print(f"{self.name} sends message to {to_user.name}: {message}")
        to_user.receive_message(message, self)

    def receive_message(self, message, from_user):
        print(f"{self.name} received message from {from_user.name}: {message}")

# 创建用户
alice = User("Alice")
bob = User("Bob")

# 添加联系人
alice.add_contact(bob)
bob.add_contact(alice)

# 发送消息
alice.send_message("Hello, Bob!", bob)
bob.send_message("Hi, Alice!", alice)

菜鸟:这样每个用户都需要知道其他用户的存在,这确实不太好。

老鸟:没错,现在我们来引入中介者模式。

引入中介者模式

老鸟:我们创建一个 ChatRoom 类作为中介者,让所有用户通过 ChatRoom 来通信。

class ChatRoom:
    def show_message(self, user, message):
        print(f"{user.name} says: {message}")

class User:
    def __init__(self, name, chatroom):
        self.name = name
        self.chatroom = chatroom

    def send_message(self, message):
        self.chatroom.show_message(self, message)

# 创建中介者
chatroom = ChatRoom()

# 创建用户
alice = User("Alice", chatroom)
bob = User("Bob", chatroom)

# 发送消息
alice.send_message("Hello, Bob!")
bob.send_message("Hi, Alice!")

菜鸟:这样看起来确实更简洁了。用户只需要知道 ChatRoom,而不需要直接引用其他用户。

问题与反思

菜鸟:可是,如果我想在发送消息时包含一些业务逻辑,比如对某些消息进行过滤,该怎么办?

老鸟:好问题。你可以在 ChatRoom 中添加相应的逻辑,这样所有的消息处理都集中在一个地方,代码更容易维护和扩展。

class ChatRoom:
    def show_message(self, user, message):
        if self.message_filter(message):
            print(f"{user.name} says: {message}")
        else:
            print(f"Message from {user.name} was blocked.")

    def message_filter(self, message):
        # 简单的示例过滤器
        return "spam" not in message.lower()

# 使用新的 ChatRoom
chatroom = ChatRoom()

alice = User("Alice", chatroom)
bob = User("Bob", chatroom)

alice.send_message("Hello, Bob!")
bob.send_message("This is spam message.")

菜鸟:明白了,这样我就可以在 ChatRoom 中集中处理所有的业务逻辑了。

优势与适用场景

老鸟:中介者模式有很多优势。它可以减少对象之间的耦合,使系统更易于扩展和维护。适用于对象之间有复杂交互的情况,比如聊天系统、GUI组件之间的通信等等。

菜鸟:明白了,这样在需要扩展用户数量或者添加新功能的时候,就不需要修改每个用户的代码了。

常见误区与优化建议

老鸟:不过要注意,不要把所有的逻辑都塞到中介者里,否则中介者会变得过于复杂。可以通过拆分中介者或引入其他设计模式来保持代码的清晰和简洁。

菜鸟:好的,我会注意的。

总结与延伸阅读

老鸟:总结一下,中介者模式通过引入一个中介者对象,来简化对象之间的通信和交互。它有助于减少对象之间的耦合,使系统更容易扩展和维护。你可以查阅《设计模式:可复用面向对象软件的基础》这本书,里面有更多设计模式的详细解释。

菜鸟:谢谢老鸟,我会去读一读的。下次我还想学习其他设计模式,你有什么推荐吗?

老鸟:你可以先了解一下观察者模式和策略模式,这两个模式也非常常用而且很有趣。

菜鸟:好的,我会去研究一下的。再次感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116880.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

H5漂流瓶社交系统源码

一个非常有创意的H5漂流瓶社交系统源码,带完整前端h5和后台管理系统。 环境:Nginx 1.20.1-MySQL 5.6.50-PHP-7.3 代码下载

python简单计算入门教程|加减法

python通过调用numpy模块,非常擅长数学计算。再通过调用matplotlib模块,可以自由自在地输出numpy计算的结果。 今天,我们就尝试一些基本计算。 下述是正弦函数和余弦函数的加法和减法计算结果。 图1 代码为: import matplotli…

【stata】处理城市名和城市代码

写了两个简单的外部命令,在这里分享一下,希望能帮到大家 1.citycode_mutate 第一个命令是citycode_mutate,用于识别字符串中可能存在的城市信息,并生成城市代码(图1图2)。 2.cityname_mutate 第二个命令…

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_word(struct pci_…

C++(一)----C++基础

1.C的发展史 C语言诞生后,很快普及使用,但是随着编程规模增大且越来越复杂,并且需要高度的抽象和建模时,C语言的诸多短板便表现了出来,为了解决软件危机,上世纪八十年代,计算机界提出了oop&…

拓扑排序-广度优先遍历思路

本质: 【广度优先遍历 】【贪心算法】应用于【有向图】的专有名词 应用场景:任务调度,课程安排 作用: 得到一个不唯一的【拓扑序】检测【有向图】是否有环,使用数据【并查集】 使用:先找度为0的前驱节点…

Linux运维排查常见故障_在tmp目录下有大量包含picture_ 的临时文件,每天晚上2 30需要对一天前的文件进行

echo“”>>/etc/security/limits.conf echo“*softnproc65535″>>/etc/security/limits.conf echo“*hardnproc65535″>>/etc/security/limits.conf echo“*softnofile65535″>>/etc/security/limits.conf echo“*hardnofile65535″>>/etc/secur…

【自动驾驶】控制算法(八)横向控制Ⅲ | 代码与模型

写在前面: 🌟 欢迎光临 清流君 的博客小天地,这里是我分享技术与心得的温馨角落。📝 个人主页:清流君_CSDN博客,期待与您一同探索 移动机器人 领域的无限可能。 🔍 本文系 清流君 原创之作&…

以太网--TCP/IP协议(一)

概述 以太网是局域网的一种,其他的比如还有令牌环、FDDI。和局域网对应的就是广域网,如Internet,城域网等。 从网络层次看,局域网协议主要偏重于低层(业内一般把物理层、数据链路层归为低层)。以太网协议…

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP…

vue动态统计图的绘画

效果图&#xff1a; 实现&#xff1a; 一、导入依赖 import echarts from echarts 二、vue的代码实现 1.在main.js导入文件 // 引入 echarts 插件 import echarts from echarts // 配置成全局组件 Vue.prototype.$echarts echarts2.代码实现 <template><!--为echa…

韩国火烧车影响出现,浙江出现限制电车进入地下车库,车主难受了

韩国电动汽车起火&#xff0c;烧毁140辆汽车&#xff0c;还导致大楼损坏以及居民受伤的后果&#xff0c;如今在中国市场也产生了影响&#xff0c;《华商报》旗下的《大风新闻》报道指&#xff0c;浙江多地的饭店、大厦禁止电动汽车进入地下车库&#xff0c;这下子电动汽车车主又…

滑动窗口在算法中的应用

滑动窗口是一种经典的算法技巧&#xff0c;就像在处理一系列动态数据时&#xff0c;用一扇可以滑动的“窗口”来捕捉一段连续的子数组或子字符串。通过不断地移动窗口的起点或终点&#xff0c;我们能够以较低的时间复杂度来解决一系列问题。在这篇文章中&#xff0c;我们将通过…

图形视频处理软件Adobe After Effects(AE)2024WIN/MAC下载及系统要求

目录 一、Adobe AE软件简介 1.1 什么是Adobe AE软件 1.2 AE软件的发展历程 1.3 AE软件的应用领域 二、Adobe AE软件下载 2.1 下载 2.2 下载注意事项 三、Adobe AE软件系统要求 3.1 最低配置要求 3.2 推荐配置要求 3.3 显示器和分辨率 四、Adobe AE软件安装与使用 …

【MacOS】mac定位服务中删除已经卸载的软件

mac定位服务中删除已经卸载的软件 网上的帖子真不靠谱 直接右键 WeTypeSettings &#xff0c;查找位置&#xff0c;丢废纸篓即可&#xff01;会提示你卸载的&#xff01;

Pyramid: Real-Time LoRa Collision Decoding with Peak Tracking技术思考与解读

一点点个人的论文解读、技术理解&#xff0c;难免会有错误&#xff0c;欢迎大家一起交流和学习~~ &#x1f600;作者关于lora的系列文章从问题陈述到方法论的提出&#xff0c;再到实验评估&#xff0c;文章结构条理清晰&#xff0c;逻辑性强&#xff0c;并深入分析了LoRa信号处…

力扣刷题(5)

整数转罗马数字 整数转罗马数字-力扣 思路&#xff1a; 把各十百千位可能出现的情况都列出来&#xff0c;写成一个二维数组找出该数的各十百千位&#xff0c;与数组中的罗马元素对应 const char* ch[4][10]{{"", "I", "II", "III"…

webpack - 五大核心概念和基本配置(打包一个简单HTML页面)

// 五大核心概念 1. entry&#xff08;入口&#xff09; 指示Webpack从哪个文件开始打包2. output&#xff08;输出&#xff09; 指示Webpack打包完的文件输出到哪里去&#xff0c;如何命名等3. loader&#xff08;加载器&#xff09; webpack本身只能处理js&#xff0c;json等…

Bev pool 加速(2):自定义c++扩展

文章目录 1. c++扩展2. 案例2.1 案例12. 1.1 代码实现(1) c++ 文件(2) setup.py编写(3) python 代码编写2.1 案例1在bevfusion论文中,将bev_pooling定义为view transform中的效率瓶颈,bevfusion 主要就是对bev_pooling进行了加速,使得视图转换的速度提高了40倍,延迟从500ms…

charles配置安卓抓包(避坑版)

下载Charleshttps://www.charlesproxy.com/安装&#xff0c;疯狂点击下一步即可注册&#xff1a;打开Charles&#xff0c;选择“Help”菜单中的“Register Charles”&#xff0c;进网站生成密钥&#xff1a;https://www.zzzmode.com/mytools/charles/,将生成的密钥填入注册重启…