欢迎访问Ningto's博客

Menu
  • 首页
  • 归档
  • 关于
  • 书签
  • 必应壁纸
  • IT聚合
  • 工具
    • 我的工具列表
    • 我的网盘
    • 必应每日壁纸API
    • Html转Markdown
    • 仙尘光标
Menu

golang 中介者模式

最后更新 2021-02-26 01:36:00   阅读量 1493

中介者模式是一种行为设计模式。此模式是创建一个中介对象,以防止对象之间的直接交互,从而避免它们之间的直接依赖关系。

一个很好的中介模式的例子是铁路系统平台,两列火车之间是相互独立的,站长充当调停者,使站台仅对其中一列列车可用。列车通过站长交互,站长维持着等候火车的队列,当任何一辆列车离开站台时,通知下一辆列车可以进入了。

注意在下面的代码中,站长是如何充当火车和站台之间的中间人。

  • 旅客列车(passengerTrain)和货物列表(goodsTrain)实现了列车接口
  • 站长(stationManger)实现了中介者(mediator )接口

代码:

package main

import (
    "fmt"
    "sync"
)

func main() {
    stationManager := newStationManger()
    passengerTrain := &passengerTrain{
        name:     fmt.Sprintf("passengerTrain%d", 1),
        mediator: stationManager,
    }

    goodsTrain := &goodsTrain{
        name:     fmt.Sprintf("goodsTrain%d", 1),
        mediator: stationManager,
    }

    passengerTrain.requestArrival()
    goodsTrain.requestArrival()
    passengerTrain.departure()

    fmt.Println("exit")
}

type mediator interface {
    canLand(train) bool
    isLanded(train) bool
    notifyFree()
}

// 列车接口
type train interface {
    requestArrival() // 请求到达
    departure()      // 离开
    permitArrival()  // 批准进入
}

// 旅客列车
type passengerTrain struct {
    name     string
    mediator mediator
}

func (g *passengerTrain) requestArrival() {
    if g.mediator.canLand(g) {
        fmt.Println(g.name + ": Landing")
    } else {
        fmt.Println(g.name + ": Waiting")
    }
}

func (g *passengerTrain) departure() {
    fmt.Println(g.name + ": Leaving")
    g.mediator.notifyFree()
}

func (g *passengerTrain) permitArrival() {
    fmt.Println(g.name + ": Arrival Permitted. Landing")
}

// 货物列车
type goodsTrain struct {
    name     string
    mediator mediator
}

func (g *goodsTrain) requestArrival() {
    if g.mediator.canLand(g) {
        fmt.Println(g.name + ": Landing")
    } else {
        fmt.Println(g.name + ": Waiting")
    }
}

func (g *goodsTrain) departure() {
    g.mediator.notifyFree()
    fmt.Println(g.name + ": Leaving")
}

func (g *goodsTrain) permitArrival() {
    fmt.Println(g.name + ": Arrival Permitted. Landing")
}

// 站长
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) isLanded(t train) bool {
    s.lock.Lock()
    defer s.lock.Unlock()
    for _, item := range s.trainQueue {
        if t == item {
            return true
        }
    }
    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()
    }
}

输出:

passengerTrain1: Landing
goodsTrain1: Waiting
passengerTrain1: Leaving
goodsTrain1: Arrival Permitted. Landing
exit
(转载本站文章请注明作者和出处:泞途 - ningto.com)

下一篇 – CentOS7 systemctl service
上一篇 – golang 单例模式

  1. Go
  2. Design

toningto@outlook.com

标签云

Life Android Javascript Python Windows Product Go Tools Java MQ Qt Node.js Tips Shell Design MongoDB Others Mac Mobile React C/C++ Web Boost Linux IOS Bug Database

推广链接

【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年99元

多谢支持,用了好几年,服务很稳定支持多设备!

其他

文章RSS

Copyright © 2016 Welcome To Ningto Blog | 鄂ICP备17003086号-2