Summer SALE
Mediator

Mediator w języku Go

Mediator to behawioralny wzorzec projektowy pozwalający zredukować sprzężenie pomiędzy komponentami programu poprzez zmuszenie ich do komunikacji za pośrednictwem obiektu zwanego mediatorem.

Mediator ułatwia modyfikację, rozszerzanie i ponowne wykorzystanie komponentów gdyż z jego pomocą nie są one zależne od wielu innych klas.

Przykład koncepcyjny

Świetnym przykładem użycia wzorca Mediator jest stacja kierowania ruchem kolejowym. Dwa pociągi nie muszą się ze sobą bezpośrednio komunikować odnośnie zajętości peronu. stationManager pełni rolę mediatora pomiędzy pociągami i pilnuje, aby tylko jeden z nich mógł wjechać na peron, zaś drugi czekał. Odjeżdżając z peronu pociąg informuje o tym fakcie stację, która z kolei udziela pozwolenia na wjazd oczekującemu pociągowi.

train.go: Komponent

package main

type Train interface {
	arrive()
	depart()
	permitArrival()
}

passengerTrain.go: Konkretny komponent

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: Konkretny komponent

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: Interfejs mediatora

package main

type Mediator interface {
	canArrive(Train) bool
	notifyAboutDeparture()
}

stationManager.go: Konkretny mediator

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: Kod klienta

package main

func main() {
	stationManager := newStationManger()

	passengerTrain := &PassengerTrain{
		mediator: stationManager,
	}
	freightTrain := &FreightTrain{
		mediator: stationManager,
	}

	passengerTrain.arrive()
	freightTrain.arrive()
	passengerTrain.depart()
}

output.txt: Wynik działania

PassengerTrain: Arrived
FreightTrain: Arrival blocked, waiting
PassengerTrain: Leaving
FreightTrain: Arrival permitted
FreightTrain: Arrived
Na podstawie: Golang By Example

Mediator w innych językach

Mediator w języku C# Mediator w języku C++ Mediator w języku Java Mediator w języku PHP Mediator w języku Python Mediator w języku Ruby Mediator w języku Rust Mediator w języku Swift Mediator w języku TypeScript