Hourra ! La version française est enfin sortie ! Laissez-nous un message svp, si vous voulez nous faire part de vos commentaires ou signaler une erreur.
Médiateur

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

Médiateur dans les autres langues

Patrons de conception : Médiateur en Java Patrons de conception : Médiateur en C# Patrons de conception : Médiateur en C++ Patrons de conception : Médiateur en PHP Patrons de conception : Médiateur en Python Patrons de conception : Médiateur en Ruby Patrons de conception : Médiateur en Swift Patrons de conception : Médiateur en TypeScript