![Médiateur](/images/patterns/cards/mediator-mini.png?id=a7e43ee8e17e4474737b1fcb3201d7ba)
Médiateur en Go
Le Médiateur est un patron de conception comportemental qui diminue le couplage entre les composants d’un programme, en les faisant communiquer indirectement, via un objet médiateur spécial.
Le médiateur rend la modification, l’extension et la réutilisation de composants individuels aisées, car ils ne dépendent plus d’une dizaine de classes.
Exemple conceptuel
Le poste d’aiguillage d’une gare est un excellent exemple du patron de conception médiateur. Deux trains ne communiquent jamais ensemble pour connaître la disponibilité d’une plateforme. Le stationManager
agit comme un médiateur : il n’autorise qu’un seul train à accéder à la plateforme et place les autres dans une file d’attente. Un train qui part va envoyer une notification au poste, ce qui permet au prochain train dans la file d’accéder à la plateforme.
train.go: Composant
package main
type Train interface {
arrive()
depart()
permitArrival()
}
passengerTrain.go: Composant concret
package main
import "fmt"
type PassengerTrain struct {
mediator Mediator
}
func (g *PassengerTrain) arrive() {
if !g.mediator.canArrive(g) {
fmt.Println("PassengerTrain: Arrival blocked, waiting")
return
}
fmt.Println("PassengerTrain: Arrived")
}
func (g *PassengerTrain) depart() {
fmt.Println("PassengerTrain: Leaving")
g.mediator.notifyAboutDeparture()
}
func (g *PassengerTrain) permitArrival() {
fmt.Println("PassengerTrain: Arrival permitted, arriving")
g.arrive()
}
freightTrain.go: Composant concret
package main
import "fmt"
type FreightTrain struct {
mediator Mediator
}
func (g *FreightTrain) arrive() {
if !g.mediator.canArrive(g) {
fmt.Println("FreightTrain: Arrival blocked, waiting")
return
}
fmt.Println("FreightTrain: Arrived")
}
func (g *FreightTrain) depart() {
fmt.Println("FreightTrain: Leaving")
g.mediator.notifyAboutDeparture()
}
func (g *FreightTrain) permitArrival() {
fmt.Println("FreightTrain: Arrival permitted")
g.arrive()
}
mediator.go: Interface médiateur
package main
type Mediator interface {
canArrive(Train) bool
notifyAboutDeparture()
}
stationManager.go: Médiateur concret
package main
type StationManager struct {
isPlatformFree bool
trainQueue []Train
}
func newStationManger() *StationManager {
return &StationManager{
isPlatformFree: true,
}
}
func (s *StationManager) canArrive(t Train) bool {
if s.isPlatformFree {
s.isPlatformFree = false
return true
}
s.trainQueue = append(s.trainQueue, t)
return false
}
func (s *StationManager) notifyAboutDeparture() {
if !s.isPlatformFree {
s.isPlatformFree = true
}
if len(s.trainQueue) > 0 {
firstTrainInQueue := s.trainQueue[0]
s.trainQueue = s.trainQueue[1:]
firstTrainInQueue.permitArrival()
}
}
main.go: Code client
package main
func main() {
stationManager := newStationManger()
passengerTrain := &PassengerTrain{
mediator: stationManager,
}
freightTrain := &FreightTrain{
mediator: stationManager,
}
passengerTrain.arrive()
freightTrain.arrive()
passengerTrain.depart()
}
output.txt: Résultat de l’exécution
PassengerTrain: Arrived
FreightTrain: Arrival blocked, waiting
PassengerTrain: Leaving
FreightTrain: Arrival permitted
FreightTrain: Arrived