[go] 中介者模式

设计模式

中介者模式是一种行为设计模式, 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。

模型说明

  1. 组件(Component)是各种包含业务逻辑的类。每个组件都有一个指向中介者的引用,该引用被声明为中介者接口类型。组件不知道中介者实际所属的类,因此你可通过将其连接到不同的中介者以使其能在其他程序中复用。

  2. 中介者(Mediator)接口声明了与组件交流的方法,但通常仅包括一个通知方法。组件可将任意上下文(包括自己的对象)作为该方法的参数,只有这样接收组件和发送者类之间才不会耦合。

  3. 具体中介者(Concrete Mediator)封装了多种组件间的关系。具体中介者通常会保存所有组件的引用并对其进行管理,甚至有时会对其生命周期进行管理。

  4. 组件并不知道其他组件的情况。如果组件内发生了重要事件,它只能通知中介者。中介者收到通知后能轻易地确定发送者,这或许已足以判断接下来需要触发的组件了。

  • 对于组件来说,中介者看上去完全就是一个黑箱。发送者不知道最终会由谁来处理自己的请求,接收者也不知道最初是谁发出了请求。

优缺点

1.优点

  • 单一职责原则:你可以将多个组件间的交流抽取到同一位置,使其更易于理解和维护。
  • 开闭原则:你无需修改实际组件就能增加新的中介者。
  • 你可以减轻应用中多个组件间的耦合情况。
  • 你可以更方便地复用各个组件。

2.缺点

  • 一段时间后,中介者可能会演化成为上帝对象

使用场景

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

参考代码

火车站交通系统。 两列火车互相之间从来不会就站台的空闲状态进行通信。
train.go: 组件

package main

type Train interface {
   
    arrive()
    depart()
    permitArrival()
}

passengerTrain.go: 具体组件

package main

import "fmt"

type PassengerTrain struct {
   
    mediator Mediator
}

func (g *PassengerTrain) arrive() {
   
    if !g.mediator.canArrive(g) {
   
        fmt.Println("PassengerTrain: Arrival blocked, waiting")
        return
    }
    fmt.Println("PassengerTrain: Arrived")
}

func (g *PassengerTrain) depart() {
   
    fmt.Println("PassengerTrain: Leaving")
    g.mediator.notifyAboutDeparture()
}

func (g *PassengerTrain) permitArrival() {
   
    fmt.Println("PassengerTrain: Arrival permitted, arriving")
    g.arrive()
}


freightTrain.go: 具体组件

package main

import "fmt"

type FreightTrain struct {
   
    mediator Mediator
}

func (g *FreightTrain) arrive() {
   
    if !g.mediator.canArrive(g) {
   
        fmt.Println("FreightTrain: Arrival blocked, waiting")
        return
    }
    fmt.Println("FreightTrain: Arrived")
}

func (g *FreightTrain) depart() {
   
    fmt.Println("FreightTrain: Leaving")
    g.mediator.notifyAboutDeparture()
}

func (g *FreightTrain) permitArrival() {
   
    fmt.Println("FreightTrain: Arrival permitted")
    g.arrive()
}


mediator.go: 中介者接口

package main

type Mediator interface {
   
    canArrive(Train) bool
    notifyAboutDeparture()
}

stationManager.go: 具体中介者

package main

type StationManager struct {
   
    isPlatformFree bool
    trainQueue     []Train
}

func newStationManger() *StationManager {
   
    return &StationManager{
   
        isPlatformFree: true,
    }
}

func (s *StationManager) canArrive(t Train) bool {
   
    if s.isPlatformFree {
   
        s.isPlatformFree = false
        return true
    }
    s.trainQueue = append(s.trainQueue, t)
    return false
}

func (s *StationManager) notifyAboutDeparture() {
   
    if !s.isPlatformFree {
   
        s.isPlatformFree = true
    }
    if len(s.trainQueue) > 0 {
   
        firstTrainInQueue := s.trainQueue[0]
        s.trainQueue = s.trainQueue[1:]
        firstTrainInQueue.permitArrival()
    }
}

main.go: 客户端代码

package main

func main() {
   
    stationManager := newStationManger()

    passengerTrain := &PassengerTrain{
   
        mediator: stationManager,
    }
    freightTrain := &FreightTrain{
   
        mediator: stationManager,
    }

    passengerTrain.arrive()
    freightTrain.arrive()
    passengerTrain.depart()
}

output:

PassengerTrain: Arrived
FreightTrain: Arrival blocked, waiting
PassengerTrain: Leaving
FreightTrain: Arrival permitted
FreightTrain: Arrived

相关推荐

  1. [go] 中介模式

    2024-01-25 14:42:04       60 阅读
  2. GO设计模式——19、中介模式(行为型)

    2024-01-25 14:42:04       74 阅读
  3. 中介模式(Mediator)

    2024-01-25 14:42:04       58 阅读
  4. ·中介模式

    2024-01-25 14:42:04       64 阅读
  5. 中介模式

    2024-01-25 14:42:04       37 阅读
  6. 设计模式——中介模式

    2024-01-25 14:42:04       55 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-25 14:42:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-25 14:42:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-25 14:42:04       82 阅读
  4. Python语言-面向对象

    2024-01-25 14:42:04       91 阅读

热门阅读

  1. git reset -hard 后,想撤回reset并恢复到reset前的版本

    2024-01-25 14:42:04       55 阅读
  2. git tag的用法详解

    2024-01-25 14:42:04       49 阅读
  3. 数据结构—基础知识(12):二叉树算法补充

    2024-01-25 14:42:04       58 阅读
  4. 阿里云 微消息队列 MQTT使用与部分常见问题处理

    2024-01-25 14:42:04       53 阅读
  5. Mysql 文件导入与导出

    2024-01-25 14:42:04       62 阅读
  6. 再学微信小程序

    2024-01-25 14:42:04       42 阅读
  7. Shell编程

    2024-01-25 14:42:04       59 阅读