golang 中介者模式
阿新 • • 發佈:2021-01-07
技術標籤:golang
中介者模式是一種行為設計模式。此模式是建立一箇中介物件,以防止物件之間的直接互動,從而避免它們之間的直接依賴關係。
一個很好的中介模式的例子是鐵路系統平臺,兩列火車之間是相互獨立的,站長充當調停者,使站臺僅對其中一列列車可用。列車通過站長互動,站長維持著等候火車的佇列,當任何一輛列車離開站臺時,通知下一輛列車可以進入了。
注意在下面的程式碼中,站長是如何充當火車和站臺之間的中間人。
- 旅客列車(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