当前位置: 首页 > 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组件之间的通信等等。

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

常见误区与优化建议

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

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

总结与延伸阅读

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

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

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

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • windows C++ 虚拟内存的按需调拨
  • Typora教程
  • 基于图谱的记忆存储 - mem0 graph memory + neo4j
  • FreeRTOS学习笔记(五)任务进阶篇
  • <Rust>egui学习之小部件(九):如何在窗口中添加下拉列表combobox部件?
  • 同城搭子怎么找?靠谱找搭子平台排行榜前十名测评
  • Typora调整图片大小:两种方式zoom或width/height
  • [数据集][目标检测]街头摊贩识别检测数据集VOC+YOLO格式758张1类别
  • 【干货分享】央企国企的群面、半结构面试复习方法和经验总结
  • Java网络编程入门
  • 【生日视频制作】保时捷车主提车交车仪式感AE模板修改文字软件生成器教程特效素材【AE模板】
  • 创建Hive表后,查看表结构发现中文注释乱码
  • 【spring】RuleOptions RecommendCtx
  • 面试—Linux
  • dpdk——数据平面开发套件
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • Android 架构优化~MVP 架构改造
  • ECS应用管理最佳实践
  • ES6系列(二)变量的解构赋值
  • github从入门到放弃(1)
  • JavaScript 一些 DOM 的知识点
  • javascript 总结(常用工具类的封装)
  • JavaScript实现分页效果
  • passportjs 源码分析
  • Redis的resp协议
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • No resource identifier found for attribute,RxJava之zip操作符
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​浅谈 Linux 中的 core dump 分析方法
  • #pragma once与条件编译
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (AngularJS)Angular 控制器之间通信初探
  • (ros//EnvironmentVariables)ros环境变量
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (一)基于IDEA的JAVA基础10
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .htaccess配置常用技巧
  • .mp4格式的视频为何不能通过video标签在chrome浏览器中播放?
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET C# 操作Neo4j图数据库
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET Framework .NET Core与 .NET 的区别
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET处理HTTP请求
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET关于 跳过SSL中遇到的问题
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • ::前边啥也没有
  • @Autowired注解的实现原理