中介者模式 (Mediator Pattern)
意图
中介者模式是一种行为型设计模式,它定义了一个中介对象,来封装一系列对象之间的交互。通过引入中介者对象,中介者模式将对象之间的复杂交互转移到中介者中,从而减少对象之间的耦合,使得系统更加灵活和可维护。
问题
在现实世界中,考虑一个复杂的聊天系统,其中多个用户可以相互发送消息。如果每个用户都直接与其他用户进行通信,会导致系统复杂度极高,并且难以管理消息传递。中介者模式可以通过引入一个聊天中介者对象,来协调用户之间的消息传递,从而简化系统设计。
解决方案
使用中介者模式,我们可以定义一个中介者接口,声明协调对象之间交互的方法。然后,创建具体的中介者类实现该接口,并在其中实现对象之间的交互逻辑。参与者对象通过中介者来进行通信,而不是直接相互通信。
模式结构
- 中介者接口(Mediator):声明协调对象之间交互的方法。
- 具体中介者(Concrete Mediator):实现中介者接口,具体协调对象之间的交互逻辑。
- 同事类(Colleague):定义与中介者交互的接口,持有中介者的引用,并通过中介者进行交互。
- 具体同事类(Concrete Colleague):实现同事类接口,并通过中介者进行具体的交互操作。
代码
以下是使用Go语言实现的中介者模式示例:
package main
import "fmt"
// 中介者接口
type Mediator interface {
Send(message string, colleague Colleague)
}
// 同事类接口
type Colleague interface {
Send(message string)
Receive(message string)
}
// 具体中介者 - 聊天中介者
type ChatMediator struct {
colleagues map[string]Colleague
}
func (m *ChatMediator) Register(name string, colleague Colleague) {
if m.colleagues == nil {
m.colleagues = make(map[string]Colleague)
}
m.colleagues[name] = colleague
}
func (m *ChatMediator) Send(message string, colleague Colleague) {
for name, c := range m.colleagues {
if c != colleague {
c.Receive(message)
}
}
}
// 具体同事类 - 用户
type User struct {
name string
mediator Mediator
}
func (u *User) Send(message string) {
fmt.Printf("%s: 发送消息: %s\n", u.name, message)
u.mediator.Send(message, u)
}
func (u *User) Receive(message string) {
fmt.Printf("%s: 接收到消息: %s\n", u.name, message)
}
func main() {
// 创建中介者
mediator := &ChatMediator{}
// 创建用户
user1 := &User{name: "Alice", mediator: mediator}
user2 := &User{name: "Bob", mediator: mediator}
user3 := &User{name: "Charlie", mediator: mediator}
// 注册用户到中介者
mediator.Register("Alice", user1)
mediator.Register("Bob", user2)
mediator.Register("Charlie", user3)
// 用户发送消息
user1.Send("你好,大家好!")
user2.Send("嗨,Alice!")
user3.Send("大家好!")
}
适用场景
- 需要处理多个对象之间复杂的交互时,并且这些交互的逻辑可能会变得复杂。
- 需要减少对象之间的直接依赖,以便于系统的维护和扩展。
- 需要集中管理对象之间的交互逻辑时,例如在一个聊天系统或事件处理系统中。
实现方式
- 定义中介者接口,声明协调对象之间交互的方法。
- 创建具体中介者类,实现中介者接口,并实现对象之间的交互逻辑。
- 定义同事类接口,声明与中介者交互的方法,并持有中介者的引用。
- 创建具体同事类,实现同事类接口,并通过中介者进行具体的交互操作。
- 客户端代码创建中介者和同事对象,并设置同事对象的中介者,然后开始交互。
优缺点
优点:
- 减少了对象之间的直接耦合,使得系统的扩展和维护更加灵活。
- 集中管理对象之间的交互逻辑,简化了系统的复杂性。
- 可以动态地调整和改变交互逻辑,而无需修改参与者对象的代码。
缺点:
- 可能会导致中介者对象变得复杂,因为它需要处理所有的交互逻辑。
- 中介者模式可能会引入额外的类,增加系统的复杂性。
其他模式的关系
- 中介者模式与观察者模式(Observer Pattern):观察者模式用于在对象状态变化时通知观察者,而中介者模式用于协调对象之间的交互。中介者模式可以与观察者模式结合使用,例如在中介者中管理观察者的通知。
- 中介者模式与责任链模式(Chain of Responsibility Pattern):责任链模式用于将请求沿着处理链传递,而中介者模式用于集中协调对象之间的交互。两者可以结合使用,例如在中介者中实现责任链的处理逻辑。
- 中介者模式与命令模式(Command Pattern):命令模式用于封装请求的操作,而中介者模式用于协调对象之间的交互。可以结合使用,例如在中介者中使用命令对象来处理请求。