<\/span><\/h2>\n\n\n\nMediator design pattern is a behavioral design pattern. This pattern suggests creating a mediator object to prevent direct communication among objects so that direct dependencies between them is avoided.<\/p>\n\n\n\n
One very good example of a mediator patter is the railway system platform. Two trains never communicate between themselves for the availability of the platform. The stationManager<\/strong> acts as a mediator and makes the platform available to only one of the trains. The train connects with stationManager<\/strong> and acts accordingly. It maintains a queue of waiting trains. In case of any train leaving a platform, it notifies one of the train to arrive on the platform next.<\/p>\n\n\n\nNotice how stationManger<\/strong> acts as a mediator between the trains<\/strong> and the platform<\/strong> in the code below.<\/p>\n\n\n\npassengerTrain and goodsTrain implement the train interface.<\/li> stationManger implements the mediator interface.<\/li><\/ul>\n\n\n\n<\/p>\n\n\n\n
<\/span>Practical Example<\/strong><\/span><\/h2>\n\n\n\ntrain.go<\/strong><\/p>\n\n\n\npackage main\n\ntype train interface {\n requestArrival()\n departure()\n permitArrival()\n}<\/code><\/pre>\n\n\n\npassengerTrain.go<\/strong><\/p>\n\n\n\npackage main\n\nimport \"fmt\"\n\ntype passengerTrain struct {\n mediator mediator\n}\n\nfunc (g *passengerTrain) requestArrival() {\n if g.mediator.canLand(g) {\n fmt.Println(\"PassengerTrain: Landing\")\n } else {\n fmt.Println(\"PassengerTrain: Waiting\")\n }\n}\n\nfunc (g *passengerTrain) departure() {\n fmt.Println(\"PassengerTrain: Leaving\")\n g.mediator.notifyFree()\n}\n\nfunc (g *passengerTrain) permitArrival() {\n fmt.Println(\"PassengerTrain: Arrival Permitted. Landing\")\n}<\/code><\/pre>\n\n\n\ngoodsTrain.go<\/strong><\/p>\n\n\n\npackage main\n\nimport \"fmt\"\n\ntype goodsTrain struct {\n mediator mediator\n}\n\nfunc (g *goodsTrain) requestArrival() {\n if g.mediator.canLand(g) {\n fmt.Println(\"GoodsTrain: Landing\")\n } else {\n fmt.Println(\"GoodsTrain: Waiting\")\n }\n}\n\nfunc (g *goodsTrain) departure() {\n g.mediator.notifyFree()\n fmt.Println(\"GoodsTrain: Leaving\")\n}\n\nfunc (g *goodsTrain) permitArrival() {\n fmt.Println(\"GoodsTrain: Arrival Permitted. Landing\")\n}<\/code><\/pre>\n\n\n\nmediator.go<\/strong><\/p>\n\n\n\npackage main\n\ntype mediator interface {\n canLand(train) bool\n notifyFree()\n}<\/code><\/pre>\n\n\n\nstationManager.go<\/strong><\/p>\n\n\n\npackage main\n\nimport \"sync\"\n\ntype stationManager struct {\n isPlatformFree bool\n lock *sync.Mutex\n trainQueue []train\n}\n\nfunc newStationManger() *stationManager {\n return &stationManager{\n isPlatformFree: true,\n lock: &sync.Mutex{},\n }\n}\n\nfunc (s *stationManager) canLand(t train) bool {\n s.lock.Lock()\n defer s.lock.Unlock()\n if s.isPlatformFree {\n s.isPlatformFree = false\n return true\n }\n s.trainQueue = append(s.trainQueue, t)\n return false\n}\n\nfunc (s *stationManager) notifyFree() {\n s.lock.Lock()\n defer s.lock.Unlock()\n if !s.isPlatformFree {\n s.isPlatformFree = true\n }\n if len(s.trainQueue) > 0 {\n firstTrainInQueue := s.trainQueue[0]\n s.trainQueue = s.trainQueue[1:]\n firstTrainInQueue.permitArrival()\n }\n}<\/code><\/pre>\n\n\n\nmain.go<\/strong><\/p>\n\n\n\npackage main\n\nfunc main() {\n stationManager := newStationManger()\n passengerTrain := &passengerTrain{\n mediator: stationManager,\n }\n goodsTrain := &goodsTrain{\n mediator: stationManager,\n }\n passengerTrain.requestArrival()\n goodsTrain.requestArrival()\n passengerTrain.departure()\n}<\/code><\/pre>\n\n\n\nOutput:<\/strong><\/p>\n\n\n\nPassengerTrain: Landing\nGoodsTrain: Waiting\nPassengerTrain: Leaving\nGoodsTrain: Arrival Permitted. Landing<\/code><\/pre>\n\n\n\n<\/p>\n\n\n\n
<\/span>Full Working Code:<\/strong><\/span><\/h2>\n\n\n\npackage main\n\nimport (\n \"fmt\"\n \"sync\"\n)\n\ntype train interface {\n requestArrival()\n departure()\n permitArrival()\n}\n\ntype passengerTrain struct {\n mediator mediator\n}\n\nfunc (g *passengerTrain) requestArrival() {\n if g.mediator.canLand(g) {\n fmt.Println(\"PassengerTrain: Landing\")\n } else {\n fmt.Println(\"PassengerTrain: Waiting\")\n }\n}\n\nfunc (g *passengerTrain) departure() {\n fmt.Println(\"PassengerTrain: Leaving\")\n g.mediator.notifyFree()\n}\n\nfunc (g *passengerTrain) permitArrival() {\n fmt.Println(\"PassengerTrain: Arrival Permitted. Landing\")\n}\n\ntype goodsTrain struct {\n mediator mediator\n}\n\nfunc (g *goodsTrain) requestArrival() {\n if g.mediator.canLand(g) {\n fmt.Println(\"GoodsTrain: Landing\")\n } else {\n fmt.Println(\"GoodsTrain: Waiting\")\n }\n}\n\nfunc (g *goodsTrain) departure() {\n g.mediator.notifyFree()\n fmt.Println(\"GoodsTrain: Leaving\")\n}\n\nfunc (g *goodsTrain) permitArrival() {\n fmt.Println(\"GoodsTrain: Arrival Permitted. Landing\")\n}\n\ntype mediator interface {\n canLand(train) bool\n notifyFree()\n}\n\ntype stationManager struct {\n isPlatformFree bool\n lock *sync.Mutex\n trainQueue []train\n}\n\nfunc newStationManger() *stationManager {\n return &stationManager{\n isPlatformFree: true,\n lock: &sync.Mutex{},\n }\n}\n\nfunc (s *stationManager) canLand(t train) bool {\n s.lock.Lock()\n defer s.lock.Unlock()\n if s.isPlatformFree {\n s.isPlatformFree = false\n return true\n }\n s.trainQueue = append(s.trainQueue, t)\n return false\n}\n\nfunc (s *stationManager) notifyFree() {\n s.lock.Lock()\n defer s.lock.Unlock()\n if !s.isPlatformFree {\n s.isPlatformFree = true\n }\n if len(s.trainQueue) > 0 {\n firstTrainInQueue := s.trainQueue[0]\n s.trainQueue = s.trainQueue[1:]\n firstTrainInQueue.permitArrival()\n }\n}\n\nfunc main() {\n stationManager := newStationManger()\n passengerTrain := &passengerTrain{\n mediator: stationManager,\n }\n goodsTrain := &goodsTrain{\n mediator: stationManager,\n }\n passengerTrain.requestArrival()\n goodsTrain.requestArrival()\n passengerTrain.departure()\n}<\/code><\/pre>\n\n\n\nOutput:<\/strong><\/p>\n\n\n\nPassengerTrain: Landing\nGoodsTrain: Waiting\nPassengerTrain: Leaving\nGoodsTrain: Arrival Permitted. Landing<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang) Table of Contents Introduction:Practical ExampleFull Working…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[1],"tags":[25,3,85],"class_list":["post-680","post","type-post","status-publish","format-standard","hentry","category-tech","tag-design-pattern","tag-go","tag-mediator"],"yoast_head":"\n
Mediator Design Pattern in Go (Golang) - Welcome To Golang By Example<\/title>\n \n \n \n \n \n \n \n \n \n \n \n \n \n\t \n\t \n\t \n