中介者模式 (Mediator Pattern)

意图

中介者模式是一种行为型设计模式,它定义了一个中介对象,来封装一系列对象之间的交互。通过引入中介者对象,中介者模式将对象之间的复杂交互转移到中介者中,从而减少对象之间的耦合,使得系统更加灵活和可维护。

问题

在现实世界中,考虑一个复杂的聊天系统,其中多个用户可以相互发送消息。如果每个用户都直接与其他用户进行通信,会导致系统复杂度极高,并且难以管理消息传递。中介者模式可以通过引入一个聊天中介者对象,来协调用户之间的消息传递,从而简化系统设计。

解决方案

使用中介者模式,我们可以定义一个中介者接口,声明协调对象之间交互的方法。然后,创建具体的中介者类实现该接口,并在其中实现对象之间的交互逻辑。参与者对象通过中介者来进行通信,而不是直接相互通信。

模式结构

  1. 中介者接口(Mediator):声明协调对象之间交互的方法。
  2. 具体中介者(Concrete Mediator):实现中介者接口,具体协调对象之间的交互逻辑。
  3. 同事类(Colleague):定义与中介者交互的接口,持有中介者的引用,并通过中介者进行交互。
  4. 具体同事类(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("大家好!")
}

适用场景

  • 需要处理多个对象之间复杂的交互时,并且这些交互的逻辑可能会变得复杂。
  • 需要减少对象之间的直接依赖,以便于系统的维护和扩展。
  • 需要集中管理对象之间的交互逻辑时,例如在一个聊天系统或事件处理系统中。

实现方式

  1. 定义中介者接口,声明协调对象之间交互的方法。
  2. 创建具体中介者类,实现中介者接口,并实现对象之间的交互逻辑。
  3. 定义同事类接口,声明与中介者交互的方法,并持有中介者的引用。
  4. 创建具体同事类,实现同事类接口,并通过中介者进行具体的交互操作。
  5. 客户端代码创建中介者和同事对象,并设置同事对象的中介者,然后开始交互。

优缺点

优点

  • 减少了对象之间的直接耦合,使得系统的扩展和维护更加灵活。
  • 集中管理对象之间的交互逻辑,简化了系统的复杂性。
  • 可以动态地调整和改变交互逻辑,而无需修改参与者对象的代码。

缺点

  • 可能会导致中介者对象变得复杂,因为它需要处理所有的交互逻辑。
  • 中介者模式可能会引入额外的类,增加系统的复杂性。

其他模式的关系

  • 中介者模式与观察者模式(Observer Pattern):观察者模式用于在对象状态变化时通知观察者,而中介者模式用于协调对象之间的交互。中介者模式可以与观察者模式结合使用,例如在中介者中管理观察者的通知。
  • 中介者模式与责任链模式(Chain of Responsibility Pattern):责任链模式用于将请求沿着处理链传递,而中介者模式用于集中协调对象之间的交互。两者可以结合使用,例如在中介者中实现责任链的处理逻辑。
  • 中介者模式与命令模式(Command Pattern):命令模式用于封装请求的操作,而中介者模式用于协调对象之间的交互。可以结合使用,例如在中介者中使用命令对象来处理请求。