中介者(Mediator)模式是一种行为型设计模式。在中介者模式中创建了一个中介对象来负责不同类间的通信。因为这些类不需要直接交互,所以也就能避免它们之间的直接依赖,实现解耦的效果。
中介者模式的一个典型案例是老式小火车站。为保证铁路系统稳定运行,两列火车一般不会直接通信,而是听从车站管理员的调度。这里车站管理员就是一个中介者。他维护着一个火车进站的调度表,让火车站一次只允许一列火车停靠。当一列火车离开车站时,他才会通知调度表中的下一趟火车进站。
下面的代码模拟了小火车站管理员调度火车的工作。
package main
import (
"fmt"
"sync"
)
// 火车类
type Train struct {
number string
mediator *Mediator
}
// 请求进站
func (t *Train) RequestGetIn() {
fmt.Println(t.number + "请求进站")
if t.mediator.canGetIn(t) {
fmt.Println("mediator:" + t.number + "可以进站停靠")
} else {
fmt.Println("mediator:" + t.number + "不能进站,请等待通知")
}
}
// 出站
func (t *Train) Departure() {
fmt.Println(t.number + "出站")
// 中介者通知其他火车可以进站了
t.mediator.notifyFree()
}
// 进站
func (t *Train) GetIn() {
fmt.Println(t.number + "已进站")
}
// 中介者
type Mediator struct {
isPlatformFree bool
lock *sync.Mutex
trainQueue []Train
}
func newMediator() *Mediator {
return &Mediator{
isPlatformFree: true,
lock: &sync.Mutex{},
}
}
func (m *Mediator) canGetIn(t *Train) bool {
m.lock.Lock()
defer m.lock.Unlock()
if m.isPlatformFree {
m.isPlatformFree = false
return true
}
m.trainQueue = append(m.trainQueue, *t)
return false
}
func (m *Mediator) notifyFree() {
m.lock.Lock()
defer m.lock.Unlock()
if !m.isPlatformFree {
m.isPlatformFree = true
fmt.Println("mediator:" + "站台已空闲")
}
if len(m.trainQueue) > 0 {
firstTrainInQueue := m.trainQueue[0]
m.trainQueue = m.trainQueue[1:]
fmt.Println("mediator:" + "允许排队中的火车进站")
firstTrainInQueue.GetIn()
}
}
func main() {
m := newMediator()
// 火车 K6801
K6801 := Train{
number: "K6801",
mediator: m,
}
// 火车 K6308
K6308 := Train{
number: "K6308",
mediator: m,
}
K6308.RequestGetIn()
K6801.RequestGetIn()
K6308.Departure()
}
运行示例代码,输出结果:
K6308请求进站
mediator:K6308可以进站停靠
K6801请求进站
mediator:K6801不能进站,请等待通知
K6308出站
mediator:站台已空闲
mediator:允许排队中的火车进站
K6801已进站
参考文章: