1. 程式人生 > 其它 >GoLang設計模式10 - 中介者模式

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!


僅是學習筆記,難免出錯,望不吝指點