一文读懂中介者设计模式

93 阅读1分钟

中介者模式是一种很常用的设计模式,它的核心是限制各个模块之间的直接交互,而是让他们通过一个中介者来沟通,这样就会减少无序和混乱

其实现实世界也有很多这样的示例,比如交警指挥交通、乐队指挥指导演奏等,这里面都有一个全局的协调者来协调其他的模块

中介者模式主要包含以下几个模块:

  • 组件:各种包含业务逻辑的类。 每个组件都有一个指向中介者的引用, 该引用被声明为中介者接口类型。
  • 中介者:接口声明了与组件交流的方法, 但通常仅包括一个通知方法
  • 具体中介者:封装了多种组件间的关系

接下来看一个具体的示例,飞机在起飞和降落的时候都是和塔台进行交互而不是和其他飞机进行交互,这里塔台就是一个中介者。

plane.go 飞机组件

package main

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

cargoPlane.go 具体组件

package main

import "fmt"

type CargoPlane struct {
    mediator Mediator
}

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

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

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

mannedPlane.go 具体组件

package main

import "fmt"

type MannedPlane struct {
    mediator Mediator
}

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

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

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

mediator.go 中介者

package main

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

manager.go 具体中介者

package main

type StationManager struct {
    isPlatformFree bool
    planeQueue     []Plane
}

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

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

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