urlname
type
Post
password
SyncToConfluence
category
业务技能
date
Apr 2, 2025
slug
fc74ab4a-9515-4c76-8ee7-ba68d781acfa
icon
Button
catalog
summary
tags
编程基础
设计模式
专业能力
软件工程
学习笔记
cover
Status
BusyTime
Status 1
status
Published
什么是中介者模式(Mediator Pattern)
中介者模式定义了一个中介对象来封装一系列对象之间的交互。它使得各个对象不需要显式地相互引用,从而降低它们之间的耦合度,并且可以独立地改变它们之间的交互。
想象一个繁忙的机场塔台(中介者 Mediator)。各个飞机(同事 Colleague)不需要直接相互通信来协调起飞和降落(这会非常混乱且危险)。相反,所有飞机都只与塔台通信,由塔台根据整体情况统一协调和指挥。塔台集中了飞机之间的交互逻辑。
中介者模式的核心在于用一个中介对象来集中管理和协调多个对象间的交互,将原本复杂的网状结构(多对多)简化为星型结构(多对一再对多)。
核心思想/步骤
- 定义中介者接口 (Mediator): 定义一个接口,用于同事对象 (Colleague) 之间的通信。它通常包含一个或多个用于传递消息或事件的方法。
- 创建具体中介者 (ConcreteMediator): 实现 Mediator 接口。它了解并维护所有的具体同事对象 (ConcreteColleague)。它负责协调同事之间的交互,并封装了它们之间的复杂依赖关系。当一个同事对象需要与其他同事通信时,它会通知中介者,由中介者将消息转发给适当的同事。
- 定义同事接口/抽象类 (Colleague): 定义一个接口或抽象类,包含一个指向 Mediator 对象的引用。每个同事对象都知道它的中介者。
- 创建具体同事 (ConcreteColleague): 实现 Colleague 接口/继承抽象类。每个具体同事类:
- 持有对其关联的 Mediator 对象的引用。
- 当需要与其他同事通信时,它不直接调用其他同事,而是调用 Mediator 的方法。
- 它也提供方法供 Mediator 在需要时调用它(例如,接收来自其他同事的消息)。
优点
- 降低耦合度 (Reduced Coupling): 同事类之间不再直接相互依赖,它们只依赖于中介者。这使得修改或替换一个同事类变得更容易,不会影响到其他同事类。
- 集中控制交互 (Centralized Control): 对象之间的交互逻辑被封装在中介者中,使得交互行为更容易理解、维护和修改。网状依赖变成了星型依赖。
- 提高对象复用性 (Increased Reusability): 同事类因为耦合度降低,可以更容易地在不同的上下文中被复用。
- 简化对象协议 (Simplified Protocols): 将多对多的复杂通信简化为一对多的通信(每个同事与中介者通信)。
可能的缺点
- 中介者可能变得庞大复杂 (Mediator Complexity): 如果系统中同事对象很多,或者它们之间的交互逻辑非常复杂,中介者类本身可能会变得非常庞大,难以维护,成为一个“上帝类”(God Object),违反了单一职责原则。
- 难以适应所有场景: 对于对象间交互逻辑非常简单直接的情况,引入中介者可能会增加不必要的复杂性。
使用场景
- 当一组对象以复杂且定义良好的方式进行交互,导致系统中存在大量的多对多依赖关系时。
- 当你想自定义一组对象之间的行为,但又不想为此创建大量的子类时。
- 当一个对象引用了许多其他对象,并且需要与它们进行通信,导致该对象变得非常复杂时。
- GUI 开发: 对话框 (Dialog) 中的各个控件(按钮、文本框、列表框)之间的交互。例如,当列表框选择改变时,可能需要启用或禁用某个按钮,更新某个文本框。Dialog 本身可以扮演中介者的角色,协调这些控件。
- 协调多个模块/服务: 在一个大型应用中,不同的子系统或模块可能需要相互协作,引入一个中介者可以管理它们之间的通信流,避免直接依赖。
- 聊天室应用: 聊天室本身是中介者,用户是同事。用户发送消息给聊天室,聊天室再将消息广播给其他用户。
- Android 中的场景:
- 复杂 Activity/Fragment 与其内部 Views 的交互: Activity 或 Fragment 可以作为中介者,协调其布局中多个 View(如 EditText, Button, RecyclerView)之间的状态和事件。例如,根据 EditText 的内容启用/禁用 Button,或根据 Button 点击更新 RecyclerView。 (虽然现在更推荐使用 ViewModel 配合 LiveData/Flow 来处理这类 UI 逻辑解耦)。
- DialogFragment: DialogFragment 常常扮演中介者的角色,协调其内部视图控件的交互,并将最终结果或事件通知给宿主 Activity/Fragment。
- 协调多个 Fragment: 一个 Activity 可以作为中介者,管理其包含的多个 Fragment 之间的通信和数据传递(同样,ViewModel 现在是更推荐的方式)。
- 多服务协调: 如果应用中有多个后台服务需要协作完成一个任务,可以引入一个中介服务来协调它们的启动、停止和数据交换。
UML 图
下面是基于“聊天室”示例的中介者模式 UML 图:
- ChatMediator (Mediator Interface): 定义了发送消息和添加用户的接口。
- User (Colleague Abstract Class): 定义了同事(用户)的通用属性(名字、中介者引用)和必须实现的方法(send, receive)。
- ChatRoom (ConcreteMediator): 实现了 ChatMediator。它内部维护一个 users 列表。sendMessage 方法会遍历列表,将消息发送给除发送者外的所有其他用户。
- ChatUser (ConcreteColleague): 继承自 User。它的 send 方法会调用 mediator.sendMessage(),它的 receive 方法用于处理接收到的消息(例如打印)。
- Client: 创建 ChatRoom 和多个 ChatUser,并将用户添加到聊天室中,然后模拟用户发送消息。
代码示例
在这个例子中:
- ChatRoom 是中介者,负责维护用户列表和转发消息。
- ChatUser 是同事,它只知道 ChatRoom(中介者),并通过它来发送消息 (send 方法调用 mediator.sendMessage)。它也实现了 receive 方法来处理来自中介者的消息。
- 用户之间没有直接的引用关系。所有的通信都通过 ChatRoom 进行。
- 客户端代码设置了环境,创建了对象,并触发了交互。
总结
- 中介者模式通过引入一个中心协调者,有效地解耦了多个对象之间的直接交互,将复杂的网状依赖简化为星型依赖。
- 它集中了交互逻辑,使得系统更容易理解和维护,同时也提高了同事对象的可复用性。
- 主要缺点是中介者本身可能变得过于复杂。
- 在 Android 中,常用于协调 UI 控件间的交互或管理不同组件(如 Fragment、Service)间的通信,但需注意避免中介者成为“上帝类”,并考虑现代架构组件(如 ViewModel)是否是更优的选择。
记住它的核心:别互相打电话了,都打给总机(中介者),总机帮你转接!
- Author:CoderWdd
- URL:https://www.wuinsights.top//article/fc74ab4a-9515-4c76-8ee7-ba68d781acfa
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts