设计模式 17 中介者模式

embedded/2025/1/15 21:48:58/

设计模式 17

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

中介者模式(Mediator Pattern)

1 定义

中介者模式将系统中多个对象之间复杂的交互和依赖关系抽象为一个中介者对象,各个对象不直接引用彼此,而是通过中介者进行通信。这样做可以减少对象之间的直接依赖,从而使系统更加易于维护和扩展。

2 结构

中介者模式包含以下角色:

  • 中介者接口(Mediator): 定义一个接口用于与各同事对象通信。
  • 具体中介者(ConcreteMediator): 实现中介者接口,协调各同事对象之间的交互。
  • 同事类(Colleague): 每个同事类都知道中介者对象,并且在需要与其他同事通信时,都会通过中介者。

UML 类图

                +---------------------------------------------------+|     Mediator                                      |+---------------------------------------------------+| + Notify(sender: Colleague, event: string): void  |+---------------------------------------------------+^|+---------------------------------------------------+|ConcreteMediator                                   |+---------------------------------------------------+| + Notify(sender: Colleague, event: string): void  || + RegisterColleague(colleague: Colleague): void   |+---------------------------------------------------++-------------------------------------------+|    Colleague                              |+-------------------------------------------+| + SetMediator(mediator: Mediator): void   || + Send(event: string): void               |+-------------------------------------------+ ^                                ^|                                |
+-------------------------------+                  +-------------------------------+
| ColleagueA                    |                  |  ColleagueB                   |
+-------------------------------+                  +-------------------------------+
| + Send(event: string): void   |                  | + Send(event: string): void   |
+-------------------------------+                  +-------------------------------+

3 示例代码

假设我们要实现一个聊天室系统,其中用户可以通过聊天室中介者互相发送消息。

中介者接口

// 中介者接口
public interface IChatMediator
{void SendMessage(string message, User user);void RegisterUser(User user);
}

具体中介者

// 具体中介者
public class ChatMediator : IChatMediator
{private readonly List<User> _users = new List<User>();public void RegisterUser(User user){_users.Add(user);}public void SendMessage(string message, User sender){foreach (var user in _users){// 不要发给自己if (user != sender){user.Receive(message);}}}
}

同事类

// 同事类
public abstract class User
{protected IChatMediator _mediator;protected string _name;public User(IChatMediator mediator, string name){_mediator = mediator;_name = name;}public abstract void Send(string message);public abstract void Receive(string message);
}// 具体同事类
public class ConcreteUser : User
{public ConcreteUser(IChatMediator mediator, string name) : base(mediator, name){}public override void Send(string message){Console.WriteLine($"{_name} sends: {message}");_mediator.SendMessage(message, this);}public override void Receive(string message){Console.WriteLine($"{_name} receives: {message}");}
}

客户端代码

class Program
{static void Main(string[] args){IChatMediator chatMediator = new ChatMediator();User user1 = new ConcreteUser(chatMediator, "User1");User user2 = new ConcreteUser(chatMediator, "User2");User user3 = new ConcreteUser(chatMediator, "User3");chatMediator.RegisterUser(user1);chatMediator.RegisterUser(user2);chatMediator.RegisterUser(user3);user1.Send("Hello, everyone!");}
}

运行结果

User1 sends: Hello, everyone!
User2 receives: Hello, everyone!
User3 receives: Hello, everyone!

在这个例子中,ChatMediator 是中介者,负责协调 User 对象之间的通信。用户通过调用中介者的 SendMessage 方法来发送消息,中介者会将消息转发给其他用户。

6 特点

  • 优点:

    • 降低耦合度: 中介者模式减少了对象之间的直接依赖,各个对象不需要知道其他对象的存在,只需要与中介者交互。

    • 增强可维护性: 对象之间的交互逻辑集中在中介者中,使得修改交互逻辑变得更加容易,而无需修改各个对象。

    • 易于扩展: 可以通过增加新的中介者或同事类来扩展系统,而不会影响现有代码。

  • 缺点:

    • 中介者复杂性: 随着系统的复杂度增加,中介者可能变得庞大且复杂,难以维护。

    • 可能引入单点故障: 中介者作为通信的中心,如果中介者失败,整个系统的通信可能会中断。

7 适用场景

  • 复杂的对象交互: 当对象之间存在复杂的交互逻辑且相互依赖时,中介者模式可以简化这些交互。
  • 系统易于扩展: 当需要在系统中添加新的交互对象而不希望影响现有代码时,中介者模式非常合适。
  • 分离系统的职责: 中介者模式可以帮助将不同对象的职责清晰地分离开来,从而减少耦合。

8 总结

中介者模式通过引入中介者对象来协调多个对象之间的交互,减少了对象之间的耦合度,并使系统更具可维护性和可扩展性。尽管中介者模式能够简化对象的交互逻辑,但需要注意中介者对象的复杂性管理,以避免其变得过于庞大。


http://www.ppmy.cn/embedded/107661.html

相关文章

Unexpected token d in JSON at position 5, check bodyParser config错误解决

错误原因&#xff1a;json格式不对 { desc"设备1", iotProjectId11 } 解决&#xff1a;通过json在线校验格式校验json格式&#xff0c;找出错误原因&#xff0c;修改 在线JSON校验格式化工具&#xff08;Be JSON&#xff09; 修改&#xff1a; {"desc": &…

【Django-vue-admin学习笔记】实现框架以外的跳过认证的页面配置

总体先说一下这种方式不推荐,因为超出本身管理后台的框架了,就相当于吧客户端部分加到服务端了,不过这里提供提供了一个解决思路,建议还是开两套服务吧。 在前端框架内实现一个Web页面应用,该应用能够通过后端API接口提交数据。 例如在一个校园管理系统的场景中,学生需…

通过 GitHub Actions 执行数据库 Schema 变更工作流

原文地址 https://www.bytebase.com/docs/tutorials/github-ci/ 教程库&#xff1a;https://github.com/bytebase/github-action-example 开发者们喜欢将 Schema 变更脚本与应用程序代码一起保存在 Git 中&#xff0c;这样变更脚本就能像应用程序代码一样接受审核和版本控制&…

Alternative account/备选科目代码配置说明 【1:1和国家科目配置运营科目】

业务场景&#xff1a; 有个关于mapping的问题&#xff1a; 1. 如果在GL account的master data里面&#xff0c;之前已经做好了alternative account的mapping, 那我要改成另外的local account,这样 A 会不会影响本地子公司的报表&#xff1f; 2. 如果GL account和alternativ…

Cesium加载高速公路样式线图层和利用CSS撰写高速公路样式

在ArcGIS软件中是将多个线图层叠加&#xff08;宽的叠加在下方防止遮盖其他图层&#xff09; 依照此想法在Cesium中加载高速公路线图层时 在 Cesium 中&#xff0c;直接设置线&#xff08;如 Polyline&#xff09;的样式为“高速公路样式”并不直接支持&#xff0c;因为 Cesiu…

STM32 ADC采样详解

Content 0x00 前言0x01 ADC配置0x02 滤波处理 0x00 前言 在单片机开发过程中&#xff0c;常常涉及到ADC的使用&#xff0c;市面上大部分便宜的传感器都是采用的ADC来获取其数据&#xff0c;如MQ-2 烟雾传感器、光敏传感器等等。 此类传感器工作原理为根据所采集到的数据变化…

linux 内核代码学习(八)

总体目标&#xff1a;由于fedora10 linux发行版中自带的linux2.6.xx内核源码规模太庞大了&#xff0c;对于想通读内核源码的爱好者来说太困难了&#xff0c;因此选择了linux2.4.20内核来进行测试&#xff08;最终是希望能够实现linux1.0内核的源码完全编译和测试&#xff09;。…

Linux远程管理工具推荐

原文阅读:【巨人肩膀社区专栏分享】Linux远程管理工具推荐 前两天xshell不让用了&#xff0c;刚好一台新电脑要装一个远程连接工具&#xff0c;准备试试其他。网上找了一些资料整理如下。 欢迎各位看官评论区说出你在使用的工具&#xff0c;期待你的使用经验分享&#xff08;…