设计模式-25-中介者模式

**中介模式(Mediator Pattern)**通过创建一个中介者对象,用于处理各个对象之间的交互。中介者对象负责解耦其他对象之间的通信,从而减少对象之间的直接依赖关系

逻辑结构

在中介者模式中,有以下几个关键角色:

  1. 中介者(Mediator):中介者定义了对象之间通信的接口,它负责协调对象之间的交互,并封装了对象之间的具体通信细节。
  2. 具体中介者(Concrete Mediator):具体中介者实现了中介者接口,它具体实现了对象之间的通信逻辑,包括接收和发送消息等。
  3. 同伴类(Colleague):同伴类是指参与中介者模式的对象,它们之间通过中介者进行通信。每个同伴类都需要持有一个中介者对象的引用。
  4. 具体同伴类(Concrete Colleague):具体同伴类实现了同伴类接口,它包含自身的一些业务逻辑,同时在需要与其他同伴类通信时,通过中介者进行消息的发送和接收
image-20230721215630514

代码实现

代码路径:https://github.com/XBoom/DesignPatterns/tree/main/24_Mediator

  1. 首先,定义同伴接口,表示同伴相互收发消息

    1
    2
    3
    4
    5
    // Colleague 同伴类接口
    type Colleague interface {
    SendMessage(message string)
    ReceiveMessage(message string)
    }
  2. 其次,定义中介者接口,表示同伴之间发送消息都需要通过中介

    1
    2
    3
    4
    // Mediator 中介者接口
    type Mediator interface {
    SendMessage(message string, colleague Colleague)
    }
  3. 接着,实现具体的中介逻辑,中介实现同伴的通信

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // ConcreteMediator 具体中介者
    type ConcreteMediator struct {
    colleague1 Colleague
    colleague2 Colleague
    }

    func (c *ConcreteMediator) SendMessage(message string, colleague Colleague) {
    if colleague == c.colleague1 {
    c.colleague2.ReceiveMessage(message)
    } else {
    c.colleague1.ReceiveMessage(message)
    }
    }
  4. 最后,定义同伴

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // ConcreteColleague 具体同伴类
    type ConcreteColleague struct {
    name string
    mediator Mediator
    }

    //发送消息
    func (c *ConcreteColleague) SendMessage(message string) {
    c.mediator.SendMessage(message, c)
    }

    func (c *ConcreteColleague) ReceiveMessage(message string) {
    fmt.Printf("%s 收到消息:%s\n", c.name, message)
    }

运行

1
2
3
4
5
6
7
8
9
10
//1. 中介对象包含具体对象
mediator := &ConcreteMediator{}
colleague1 := &ConcreteColleague{name: "Colleague1", mediator: mediator}
colleague2 := &ConcreteColleague{name: "Colleague2", mediator: mediator}
//2. 中介双方
mediator.colleague1 = colleague1
mediator.colleague2 = colleague2
//3. 发送消息
colleague1.SendMessage("Hello, colleague2!")
colleague2.SendMessage("Hi, colleague1!")

结果

1
2
Colleague2 收到消息:Hello, colleague2!
Colleague1 收到消息:Hi, colleague1!

中介者模式与观察者模式的区别?

在观察者模式中,尽管一个参与者既可以是观察者,同时也可以是被观察者,但大部分情况下,交互关系往往都是单向的,一个参与者要么是观察者,要么是被观察者,不会兼具两种身份。

而中介模式正好相反。只有当参与者之间的交互关系错综复杂,维护成本很高的时候,才考虑使用中介模式。而且,如果一个参与者状态的改变,其他参与者执行的操作有一定先后顺序的要求,这个时候,中介模式就可以利用中介类,通过先后调用不同参与者的方法,来实现顺序的控制,而观察者模式是无法实现这样的顺序要求的

适用场景

  1. 当一些对象和其他对象紧密耦合以致难以对其进行修改时
  2. 当组件因过于依赖其他组件而无法在不同应用中复用时,可使用中介者模式
  3. 如果为了能在不同情景下复用一些基本行为,导致需要被迫创建大量组件子类时

总结

  1. 单一职责原则。 可以将多个组件间的交流抽取到同一位置, 使其更易于理解和维护。
  2. 开闭原则。 无需修改实际组件就能增加新的中介者
  3. 可以减轻应用中多个组件间的耦合情况
  4. 可以更方便地复用各个组件
  5. 中介模式会产生大而复杂的上帝类

参考链接

  1. https://refactoringguru.cn/design-patterns/mediator
  2. https://lailin.xyz/post/mediator.html