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

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

引导性开场

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

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

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

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

渐进式介绍概念

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

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

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

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

Python代码示例,逐步展开

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

基础实现

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

class User:def __init__(self, name):self.name = nameself.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 = nameself.chatroom = chatroomdef 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组件之间的通信等等。

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

常见误区与优化建议

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

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

总结与延伸阅读

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

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

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

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

相关文章:

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

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

深度学习-物体检测YOLO(You only look once)

目录 一:YOLO算法的网络结构 流程 1.图像分割 2.图片在网格中的处理 3.非极大值抑制 二:训练 三:分类误差 四:与Faster R-CNN对比 一:YOLO算法的网络结构 GooleNet4个卷积2个全连接层 流程 输入原始图片resize到…...

redisson中的分布式锁

我的博客大纲 我的后端学习大纲 a.redisson概述: 1.Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)2.redisson介绍官方文档地址:3.Redisson它不仅提供了一系列的分布式的Java常用对象,还…...

如何将镜像推送到docker hub

前言 这一篇应该是最近最后一篇关于docker的博客了,咱来个有始有终,将最后一步——上传镜像给他写完,废话不多说,直接进入正题。 登录 首先需要确保登录才能推送到你的仓库中去,在终端输入docker login,输入用户名和…...

GO 匿名函数

GO 匿名函数 文章目录 GO 匿名函数1. **回调函数**2. **goroutine 中的操作**3. **延迟操作(defer)**4. **内联处理逻辑**5. **闭包**6. **过滤、映射等函数式编程风格**7. **测试中的临时逻辑**8. **短期存在的逻辑操作**总结 匿名函数在 Go 语言中的使…...

JuiceFS 在多云架构中加速大模型推理

在大模型的开发与应用中,数据预处理、模型开发、训练和推理构成四个关键环节。本文将重点探讨推理环节。在之前的博客中,社区用户 BentoML 和贝壳的案例提到了使用 JuiceFS 社区版来提高模型加载的效率。本文将结合我们的实际经验,详细介绍企…...

【DCL】Dual Contrastive Learning for General Face Forgery Detection

文章目录 Dual Contrastive Learning for General Face Forgery Detectionkey points:贡献方法数据视图生成对比学习架构实例间对比学习实例内对比学习总损失函数实验实验细节定量结果跨数据集评估跨操作评估消融实验可视化Dual Contrastive Learning for General Face Forgery…...

https的特点

https的特点 优点:缺点:HTTPS是如何保证安全的? 优点: 使用HTTPS协议可以认证用户和服务器,确保数据发送到正确的客户端和服务器;使用HTTPS协议可以进行加密传输、身份认证,通信更加安全、防止…...

〖open-mmlab: MMDetection〗解析文件:mmdet/models/losses/cross_entropy_loss.py

目录 深入解析MMDetection中的CrossEntropyLoss及其应用1. 概述2. 核心函数2.1 cross_entropy2.1.1 函数定义和参数说明2.1.2 函数体2.1.3 总结 2.2 binary_cross_entropy2.2.1 _expand_onehot_labels函数2.2.2 binary_cross_entropy函数2.2.3 总结 2.3 mask_cross_entropy2.3.…...

【PyTorch单点知识】torch.nn.Embedding模块介绍:理解词向量与实现

文章目录 0. 前言1. 基础介绍1.1 基本参数1.2 可选参数1.3 属性1.4 PyTorch源码注释 2. 实例演示3. embedding_dim的合理设定4. 结论 0. 前言 按照国际惯例,首先声明:本文只是我自己学习的理解,虽然参考了他人的宝贵见解及成果,但…...

Jedis 操作 Redis 数据结构全攻略

Jedis 操作 Redis 数据结构全攻略 一 . 认识 RESP二 . 前置操作2.1 创建项目2.2 关于开放 Redis 端口的问题2.2.1 端口转发?2.2.2 端口配置 2.3 连接到 Redis 服务器 三 . 通用命令3.1 set 和 get3.2 exists 和 del3.3 keys3.4 expire、ttl、type 三 . string 相关命令3.1 mse…...

ctf.show靶场ssrf攻略

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 web351 解析:post传入url参数他就会访问。 解法: hackbar传入url参数写入https://127.0.0.1/flag.php web352 解析:post传入url参数,不能是127.0.0.1和localhost 解法:缩写127.1传入 web353 解析…...

在 PyTorch 中,如何使用 `pack_padded_sequence` 来提高模型训练的效率?

在PyTorch中,pack_padded_sequence 是一个非常有用的函数,它可以用来提高模型训练的效率,特别是在处理变长序列数据时。这个函数的主要作用是将填充后的序列数据打包,以便循环神经网络(RNN)可以更高效地处理…...

Gossip协议

主要用在Redis Cluster 节点间通信 Gossip协议,也称为流行病协议(Epidemic Protocol),是一种在分布式系统中用于信息传播和故障探测的算法。 一、工作原理 随机选择传播对象 每个节点会定期随机选择一些其他节点作为传播对象。这…...

数据结构————双向链表

内存泄漏: 内存泄漏(Memory Leak)是指程序中已动态分配的内存由于某种原因程序未释放或无法释放,导致系统内存的浪费,严重时会导致程序运行缓慢甚至崩溃。这种情况在长时间运行的程序或大型系统中尤为常见&#xff0c…...

55 - I. 二叉树的深度

comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9855%20-%20I.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%B7%B1%E5%BA%A6/README.md 面试题 55 - I. 二叉树的深度 题目描述 输入一棵二叉树的根节点…...

Redis——初识Redis

初识Redis Redis认识Redis 分布式系统单机架构为什么要引入分布式理解负载均衡数据库的读写分离引入主从数据库 引入缓存数据库分库分表业务拆分——微服务常见概念了解 Redis背景介绍特性应用场景Redis不能做的事情Redis客户端redis客户端的多种形态 Redis 认识Redis 存储数…...

Xshell or Xftp提示“要继续使用此程序,您必须应用最新的更新或使用新版本”

Xshell提示“要继续使用此程序,您必须应用最新的更新或使用新版本”,笔者版本是xshell 6 方法一:更改系统时间 对于Windows 10用户,首先找到系统日期,右键点击并选择“调整时间/日期”。将日期设定为上一年。完成调整后&#x…...

table用position: sticky固定多层表头,滑动滚动条border边框透明解决方法

问题:我发现,这个上下滑动有内容经过就会出现如图的情况。 解决的方法:用outline(轮廓)替代border,以达到我们想要的样式。 outline主要是在元素边框的外围设置轮廓,outline不占据空间,绘制于…...

基于飞桨paddle2.6.1+cuda11.7+paddleRS开发版的目标提取-道路数据集训练和预测代码

基于飞桨paddle2.6.1cuda11.7paddleRS开发版的目标提取-道路数据集训练和预测代码 预测结果: 预测影像: (一)准备道路数据集 下载数据集地址: https://aistudio.baidu.com/datasetdetail/56961 mass_road.zip …...

AI赋能泳装设计,今夏爆款如何诞生?

AI赋能泳装设计,今夏爆款如何诞生?随着气温攀升,泳装市场迎来销售旺季。北京先智先行科技有限公司凭借"先知大模型"、“先行AI商学院”、"先知AIGC超级工场"三大旗舰产品,正为泳装行业注入全新活力。传统泳装…...

DLSS Swapper终极指南:如何免费智能管理游戏DLSS文件,提升游戏性能

DLSS Swapper终极指南:如何免费智能管理游戏DLSS文件,提升游戏性能 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 你是否厌倦了每次游戏更新后手动替换DLSS文件的繁琐操作?你是否希…...

dSPACE ControlDesk实战:从虚拟CAN信号注入到动态仪表板构建

1. 虚拟CAN信号注入实战 第一次接触dSPACE ControlDesk时,最让我头疼的就是在没有实体ECU的情况下如何模拟CAN总线信号。后来发现ControlDesk自带的CAN Generator工具简直就是虚拟测试的"救命稻草"。这个工具可以完美模拟真实ECU发出的CAN信号&#xff0c…...

AI 写作一键生成超简单,焦圈儿免费积分福利等你来领

「现在写一篇公众号推文,没三四个小时都下不来。」一位做个人 IP 的朋友跟我抱怨。问题不在于工具太少,而在于门槛太高, 要么你得自己熬夜改稿,要么你得学一堆复杂 Prompt,才能把 AI 伺候好。内容行业正在进入一个悖论…...

数据分析篇---U型关系与与阈值效应

在数据科学、经济学和医学研究中,“U型关系”和“阈值效应”是两种非常经典且重要的非线性模式。它们描述的是变量之间并非简单的“越多越好”的直线关系,而是存在转折点。可以把线性关系想象成匀速开车,而U型和阈值效应则像是开车时遇到的上…...

双人成行2026最新官方正版免费下载 520情侣必玩 一键转存 永久更新 (看到速转存 资源随时走丢)

下载链接 # 编织奇迹的合作历程:《双人成行》的幕后、机制与同类作品剖析 在现代电子游戏领域,纯粹专注于双人合作的游戏并不多见,而能将其做到极致并斩获行业高额荣誉的作品,更是凤毛麟角。由Hazelight Studios开发的《双人成行…...

npc_gzip异常处理与调试手册:解决压缩器错误的10个实用技巧

npc_gzip异常处理与调试手册:解决压缩器错误的10个实用技巧 【免费下载链接】npc_gzip Code for Paper: “Low-Resource” Text Classification: A Parameter-Free Classification Method with Compressors 项目地址: https://gitcode.com/gh_mirrors/np/npc_gzip…...

保姆级教程:用VASP+VTST脚本搞定CI-NEB过渡态计算(从编译到出图)

从零构建VASPVTST的CI-NEB计算体系:科研级过渡态求解实战指南 在计算材料科学领域,精确确定化学反应或扩散过程的过渡态结构是理解反应机理的关键。传统NEB方法虽能描绘反应路径,但对鞍点的定位精度有限——这正是CI-NEB方法的价值所在。本文…...

Linux 新手必会 30 个高频基础命令(零基础可直接上手)

前言对于Linux新手来说,无需死记硬背所有命令,重点掌握这30个高频基础命令,就能完成日常90%的操作(目录切换、文件管理、系统查看等)。本文按“使用场景分类”,每个命令标注【用法示例新手提示】&#xff0…...

从CVE到ATTCK:如何用Elastic Stack构建你的个人安全情报仪表盘

从CVE到ATT&CK:如何用Elastic Stack构建你的个人安全情报仪表盘 在安全运营领域,数据孤岛一直是分析师面临的主要挑战。CVE漏洞数据库、CWE弱点分类、CAPEC攻击模式以及ATT&CK框架各自提供了宝贵的安全情报,但这些数据往往分散在不同…...