GoLang设计模式10 - 中介者模式

中介者模式是一种行为型设计模式。在中介者模式中创建了一个中介对象来负责不同类间的通信。因为这些类不需要直接交互,所以也就能避免它们之间的直接依赖,实现解耦的效果。

中介者模式的一个典型案例是老式小火车站。为保证铁路系统稳定运行,两列火车一般不会直接通信,而是听从车站管理员的调度。这里车站管理员就是一个中介者。他维护着一个火车进站的调度表,让火车站一次只允许一列火车停靠。当一列火车离开车站时,他才会通知调度表中的下一趟火车进站。

下面的代码模拟了小火车站管理员调度火车的工作。

火车接口 train.go :

1
2
3
4
5
6
7
8
type train interface {
 
    requestArrival()
 
    departure()
 
    permitArrival()
}

客车类(passengerTrain)和货车类(goodsTrain)分别实现了train接口。

passengerTrain.go :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import "fmt"
 
type passengerTrain struct {
    mediator mediator
}
 
func (g *passengerTrain) requestArrival() {
    if g.mediator.canLand(g) {
        fmt.Println("PassengerTrain: Landing")
    else {
        fmt.Println("PassengerTrain: Waiting")
    }
}
 
func (g *passengerTrain) departure() {
    fmt.Println("PassengerTrain: Leaving")
    g.mediator.notifyFree()
}
 
func (g *passengerTrain) permitArrival() {
    fmt.Println("PassengerTrain: Arrival Permitted. Landing")
}

  goodsTrain.go :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import "fmt"
 
type goodsTrain struct {
    mediator mediator
}
 
func (g *goodsTrain) requestArrival() {
    if g.mediator.canLand(g) {
        fmt.Println("GoodsTrain: Landing")
    else {
        fmt.Println("GoodsTrain: Waiting")
    }
}
 
func (g *goodsTrain) departure() {
    g.mediator.notifyFree()
    fmt.Println("GoodsTrain: Leaving")
}
 
func (g *goodsTrain) permitArrival() {
    fmt.Println("GoodsTrain: Arrival Permitted. Landing")
}

中介者接口 mediator.go:

1
2
3
4
5
6
type mediator interface {
 
    canLand(train) bool
 
    notifyFree()
}

车站管理员实现了mediator接口, stationManager.go:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import "sync"
 
type stationManager struct {
    isPlatformFree bool
    lock           *sync.Mutex
    trainQueue     []train
}
 
func newStationManger() *stationManager {
    return &stationManager{
        isPlatformFree: true,
        lock:           &sync.Mutex{},
    }
}
 
func (s *stationManager) canLand(t train) bool {
    s.lock.Lock()
    defer s.lock.Unlock()
    if s.isPlatformFree {
        s.isPlatformFree = false
        return true
    }
    s.trainQueue = append(s.trainQueue, t)
    return false
}
 
func (s *stationManager) notifyFree() {
    s.lock.Lock()
    defer s.lock.Unlock()
    if !s.isPlatformFree {
        s.isPlatformFree = true
    }
    if len(s.trainQueue) > 0 {
        firstTrainInQueue := s.trainQueue[0]
        s.trainQueue = s.trainQueue[1:]
        firstTrainInQueue.permitArrival()
    }
}

main.go:

1
2
3
4
5
6
7
8
9
10
11
12
func main() {
    stationManager := newStationManger()
    passengerTrain := &passengerTrain{
        mediator: stationManager,
    }
    goodsTrain := &goodsTrain{
        mediator: stationManager,
    }
    passengerTrain.requestArrival()
    goodsTrain.requestArrival()
    passengerTrain.departure()
}

执行结果:

1
2
3
4
PassengerTrain: Landing
GoodsTrain: Waiting
PassengerTrain: Leaving
GoodsTrain: Arrival Permitted. Landing

代码已上传至GitHub: zhyea / go-patterns / mediator-pattern 

END!

 


仅是学习笔记,难免出错,望不吝指点
 
转 https://www.cnblogs.com/amunote/p/15415573.html
posted @   dreamw  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示