21 设计模式之中介者模式

ops/2024/12/12 9:55:26/

一、什么是中介者模式

        中介者模式属于行为型设计模式,它的核心思想是:将对象之间的交互交给一个中介者对象来处理,而不是让对象之间直接通信这样做的好处是减少了类与类之间的耦合,使得系统更加松散,便于维护和扩展。

        在软件设计中,经常会遇到多个对象之间需要互相通信的场景。随着对象数量的增多,它们之间的交互关系变得越来越复杂。这时候,如何有效管理这些对象之间的依赖关系,避免过度耦合,成为了我们必须面对的问题。

        在这种情况下,中介者模式(Mediator Pattern) 提供了一个优雅的解决方案。它通过引入一个中介者对象来协调多个对象之间的交互,从而减少了对象之间的直接依赖。本文将通过一个简单的示例来讲解中介者模式的应用。


二、中介者模式的结构

  • Mediator(中介者接口):定义了与同事类的交互接口,通常包括注册同事对象和转发消息的方法。
  • ConcreteMediator(具体中介者):实现了Mediator接口,协调所有同事对象之间的交互。
  • Colleague(同事类):每个同事对象都持有一个中介者实例,通过中介者与其他同事对象进行通信。
  • ConcreteColleague(具体同事类):具体的同事对象,定义了自己的行为,并通过中介者与其他同事交互。

三、示例代码

        以下是一个模拟的例子,我们在其中实现了一个简单的消息传递系统,两个同事对象通过中介者交换信息。

1. 定义中介者抽象类

java">public abstract class Mediator {public abstract void register(Colleague colleague);  // 注册同事public abstract void relay(Colleague cl);  // 转发消息
}

Mediator 类定义了两个方法:

  • register(Colleague colleague):注册同事对象。
  • relay(Colleague cl):转发消息。当一个同事发送请求时,调用此方法将请求传递给其他同事。

2. 实现具体中介者

java">public class ConcreteMediator extends Mediator {private List<Colleague> colleagues = new ArrayList<Colleague>();  // 存储同事对象@Overridepublic void register(Colleague colleague) {if (!colleagues.contains(colleague)) {colleagues.add(colleague);  // 注册同事对象colleague.setMediator(this);  // 设置中介者}}@Overridepublic void relay(Colleague cl) {for (Colleague colleague : colleagues) {if (!colleague.equals(cl)) {  // 排除发送消息的同事colleague.receive();  // 通知其他同事}}}
}

        在 ConcreteMediator 中,我们维护了一个同事列表 colleagues。当一个同事发送消息时,relay() 方法会将消息传递给其他所有同事(不包括发送消息的同事本身)。

3. 定义同事类

java">public abstract class Colleague {protected Mediator mediator;  // 中介者对象public void setMediator(Mediator mediator) {this.mediator = mediator;  // 设置中介者}public abstract void receive();  // 接收请求的方法public abstract void send();  // 发送请求的方法
}

  Colleague 类是所有同事类的基类,每个同事都需要通过中介者与其他同事交互。具体的同事类会实现 receive()send() 方法。

4. 具体同事类

java">public class ConcreteColleague1 extends Colleague {@Overridepublic void receive() {System.out.println("具体同事类1收到请求");}@Overridepublic void send() {System.out.println("具体同事类1发出请求");mediator.relay(this);  // 通过中介者通知其他同事}
}
java">public class ConcreteColleague2 extends Colleague {@Overridepublic void receive() {System.out.println("具体同事类2收到请求");}@Overridepublic void send() {System.out.println("具体同事类2发出请求");mediator.relay(this);  // 通过中介者通知其他同事}
}

  ConcreteColleague1ConcreteColleague2 实现了 Colleague 类,并在 send() 方法中调用中介者的 relay() 方法,将消息传递给其他同事。

5. 测试类

java">public class TestMediator {public static void main(String[] args) {// 实例化中介者Mediator mediator = new ConcreteMediator();// 实例化同事Colleague colleague1 = new ConcreteColleague1();Colleague colleague2 = new ConcreteColleague2();// 注册同事mediator.register(colleague1);mediator.register(colleague2);// 同事1发出请求colleague1.send();System.out.println("-------------------------------------------------------");// 同事2发出请求colleague2.send();}
}

        在 TestMediator 中,我们实例化了一个中介者 ConcreteMediator 和两个同事 ConcreteColleague1ConcreteColleague2。通过 mediator.register() 方法将同事注册到中介者中,然后调用 send() 方法模拟同事之间的消息传递。

6.输出结果

具体同事类1发出请求
具体同事类2收到请求
-------------------------------------------------------
具体同事类2发出请求
具体同事类1收到请求

        从输出结果可以看到,当同事1发出请求时,同事2收到了请求;同理,当同事2发出请求时,同事1收到了请求。这是因为消息传递通过中介者进行,避免了同事之间直接通信。


四、中介者模式的优缺点

1.优点

  • 降低类之间的耦合度

    • 中介者模式将多个对象之间的交互集中管理,不再由每个对象直接引用其他对象。通过中介者来协调所有对象的行为,从而有效降低了对象之间的耦合度,避免了对象之间的复杂依赖关系。
    • 例如,在我们的示例中,ConcreteColleague1ConcreteColleague2 不再直接互相通信,它们只通过中介者 ConcreteMediator 来传递消息。这使得同事之间的关系更加清晰,并且容易维护。
  • 集中管理对象间的通信

    • 中介者模式使得通信的管理更加集中化,所有的消息传递和请求处理都通过一个统一的中介者来处理。这减少了类与类之间的交互路径,避免了多对多的直接关系。
    • 例如,如果你有很多同事对象需要互相通知,通过中介者来协调它们的通信将使得系统更加清晰和简洁。
  • 简化对象间的交互逻辑

    • 在没有中介者的情况下,同事对象需要彼此直接通信,可能会导致复杂的控制逻辑和依赖关系。而中介者模式通过将交互逻辑集中到中介者类中,使得每个同事对象只需要处理自己的行为和与中介者的交互,简化了整体的交互流程。
    • 例如,ConcreteColleague1ConcreteColleague2 只关心自己接收和发送消息,而不需要知道其他同事的存在或与它们的具体交互。
  • 增强系统的可扩展性

    • 如果需要增加新的同事对象,只需要创建新的同事类,并将其注册到中介者中即可,无需修改其他同事的代码。这符合开闭原则(对扩展开放,对修改关闭)。
    • 例如,若要新增一个 ConcreteColleague3 类,只需要在 TestMediator 中注册并实现其行为,而不需要修改 ConcreteColleague1ConcreteColleague2 的实现。

2.缺点

  • 中介者类可能过于庞大

    • 由于中介者模式将所有的交互逻辑集中到一个中介者类中,随着系统的增长和同事对象的增加,ConcreteMediator 类可能变得非常复杂和庞大。所有的交互和控制逻辑都被集中在一个类中,这可能导致中介者成为一个“上帝类”,难以维护和扩展。
    • 例如,当有大量同事类和它们之间复杂的交互关系时,中介者可能需要处理过多的分支逻辑,导致代码难以管理。
  • 违反单一职责原则(SRP)

    • 中介者类的职责是协调所有同事类之间的通信,随着功能的增加,中介者类可能需要处理过多的职责,从而违反了单一职责原则(SRP)。在某些复杂场景下,单一的中介者类可能承担了过多的职责,导致其维护和扩展变得困难。
    • 例如,ConcreteMediator 类不仅需要负责注册同事,还需要处理所有同事之间的消息转发,这些行为可能来自不同的领域或模块,导致中介者类的职责过于宽泛。
  • 增加了中介者的复杂性

    • 中介者模式引入了中介者对象,可能会导致额外的复杂性。虽然它减少了同事对象之间的交互复杂性,但同时也带来了中介者本身的设计复杂性,特别是当系统中有多个中介者时,管理这些中介者的交互和职责也变得更加复杂。
    • 例如,系统中有多个中介者时,如何划分职责、如何协调不同中介者之间的关系,都是需要考虑的问题。
  • 难以处理复杂的交互逻辑

    • 在一些场景中,多个同事之间的交互可能涉及到复杂的业务逻辑。如果所有的逻辑都集中在中介者类中,可能会导致业务逻辑的高度集中,难以测试和维护。特别是当业务逻辑涉及多个领域模型时,单一的中介者可能无法有效处理这些复杂的交互。
    • 例如,如果每个同事类与其他同事类的交互都非常复杂,且每个同事类还需要执行额外的业务操作,那么仅靠中介者来处理这些交互,可能会使得中介者的代码变得难以管理和维护。

五、适用场景

尽管中介者模式有一些缺点,但它在以下场景中非常有效:

  • 复杂的交互:当系统中有多个对象需要相互协作时,可以使用中介者模式来集中管理这些对象的交互,简化通信流程。
  • 减少类之间的耦合:当多个对象之间的交互关系过于复杂且紧密时,使用中介者模式可以有效降低类与类之间的耦合度。
  • 松散耦合的系统:如果系统中的多个组件需要互相协调,但又不希望它们之间有直接依赖关系时,中介者模式可以帮助实现松散耦合。

六、总结

        中介者模式通过引入一个中介者来协调对象之间的交互,减少了对象之间的直接依赖,降低了系统的复杂度。它使得对象之间的交互变得更加清晰,并增强了系统的可扩展性。然而,在使用中介者模式时,我们需要注意中介者可能变得过于庞大和复杂,因此合理地设计中介者的职责和功能是非常重要的。

        通过本文的示例和分析,相信你已经对中介者模式的优缺点有了更深入的理解。在实际开发中,根据具体需求来选择是否使用中介者模式,可以帮助你更加灵活地应对复杂的交互场景。


http://www.ppmy.cn/ops/141216.html

相关文章

在Liunx中安装JDK、Tomcat、mysql、Nginx

一.软件安装方式 在Linux系统中&#xff0c;安装软件的方式主要有四种&#xff0c;这四种安装方式的特点如下&#xff1a; 二.安装JDK 上述我们介绍了Linux系统软件安装的四种形式&#xff0c;接下来我们就通过第一种(二进制发 布包)形式来安装JDK。 在/下创建soft目录&…

从 HTTP 到 HTTPS 再到 HSTS

近些年&#xff0c;随着域名劫持、信息泄漏等网络安全事件的频繁发生&#xff0c;网站安全也变得越来越重要&#xff0c;也促成了网络传输协议从 HTTP 到 HTTPS 再到 HSTS 的转变。 HTTP HTTP&#xff08;超文本传输协议&#xff09; 是一种用于分布式、协作式和超媒体信息系…

【UE5】制作插件 并调试【vs2022】

视频教程&#xff1a;好看视频-轻松有收获 https://www.youtube.com/watch?vIjpa9mI2b5I 官方&#xff1a;https://dev.epicgames.com/documentation/zh-cn/unreal-engine/plugins-in-unreal-engine 原文&#xff1a;【UE】制作插件_ue插件-CSDN博客 C制作插件 1. 我们可…

Dubbo应用篇

文章目录 一、Dubbo简介二、SSM项目整合Dubbo1.生产者方配置2.消费者方配置 三、Spring Boot 项目整合Dubbo1.生产者方配置2.消费者方配置 四、应用案例五、Dubbo配置的优先级别1. 方法级配置&#xff08;Highest Priority&#xff09;2. 接口级配置3. 消费者/提供者级配置4. 全…

‌System Prompt VS User Prompt

System Prompt&#xff08;系统提示词&#xff09;与User Prompt&#xff08;用户提示词&#xff09;在定义、作用和特点上存在显著区别。‌ 定义 ‌System Prompt‌&#xff1a;系统提示词是指向AI提供的一组初始指令或背景信息&#xff0c;用于指导AI的行为方式和响应模式。…

设计模式之工厂模式:从汽车工厂到代码工厂

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 工厂模式概述 想象一下你走进一家4S店准备买车。作为顾客&#xff0c;你不需要知道汽车是如何被制造出来的&#xff0c;你只需要告诉销售顾问&a…

如何使用 Python 实现简单的 Web 服务器?

为了实现一个简单的Web服务器&#xff0c;Python提供了多种方法。对于快速原型设计和学习目的来说&#xff0c;最简单的方法之一是使用内置的http.server模块。 然而&#xff0c;在实际开发中&#xff0c;更常见的做法是使用像Flask或Django这样的框架来构建更为复杂的应用程序…

牛客网刷题SQL--高级查询

目录 SQL16--查找GPA最高值 描述 示例1 答案 其他方法&#xff1a; SQL17--计算男生人数以及平均GPA 描述 示例1 答案 SQL18--分组计算练习题 描述 示例1 答案 SQL19--分组过滤练习题 描述 示例1 答案 SQL20--分组排序练习题 描述 示例1 答案 SQL16--查找GP…