• GoLang设计模式10


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

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

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

    火车接口 train.go :

    type train interface {
    
    	requestArrival()
    
    	departure()
    
    	permitArrival()
    }
    

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

    passengerTrain.go :

    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 :

    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:

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

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

    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:

    func main() {
    	stationManager := newStationManger()
    	passengerTrain := &passengerTrain{
    		mediator: stationManager,
    	}
    	goodsTrain := &goodsTrain{
    		mediator: stationManager,
    	}
    	passengerTrain.requestArrival()
    	goodsTrain.requestArrival()
    	passengerTrain.departure()
    }
    

    执行结果:

    PassengerTrain: Landing
    GoodsTrain: Waiting
    PassengerTrain: Leaving
    GoodsTrain: Arrival Permitted. Landing
    

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

    END!


    仅是学习笔记,难免出错,望不吝指点
  • 相关阅读:
    lrzsz踩坑记
    《西安游记》
    《这世界那么多人》
    Go 日常开发常备第三方库和工具
    Go 里的超时控制
    菜鸟轻松拿offer: 软件测试工程师面试秘笈
    Django 练习教程
    JasperReports入门教程(五):分组打印
    并发的特性和锁的原理,分类
    面试高频算法
  • 原文地址:https://www.cnblogs.com/amunote/p/15415573.html
Copyright © 2020-2023  润新知