Viva! A versão em Português Brasileiro finalmente foi lançada! Por favor, envie-nos uma mensagem se você quer compartilhar sua opinião ou relatar um erro.
Mediator

Mediator em Go

O Mediator é um padrão de projeto comportamental que reduz o acoplamento entre os componentes de um programa, fazendo-os se comunicar indiretamente, por meio de um objeto mediador especial.

O Mediator facilita a modificação, a extensão e a reutilização de componentes individuais porque eles não são mais dependentes de dezenas de outras classes.

Exemplo conceitual

Um excelente exemplo do padrão Mediator é um sistema de tráfego de estação ferroviária. Dois trens nunca se comunicam entre si pela disponibilidade da plataforma. O stationManager atua como um mediador e disponibiliza a plataforma para apenas um dos trens que chegam, mantendo os demais em uma fila. Um trem partindo notifica as estações, o que permite que o próximo trem na fila chegue.

train.go: Componente

package main

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

passengerTrain.go: Componente concreto

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: Componente concreto

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 do mediador

package main

type mediator interface {
	canArrive(train) bool
	notifyAboutDeparture()
}

stationManager.go: Mediador concreto

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: Código cliente

package main

func main() {
	stationManager := newStationManger()

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

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

output.txt: Resultados da execução

PassengerTrain: Arrived
FreightTrain: Arrival blocked, waiting
PassengerTrain: Leaving
FreightTrain: Arrival permitted
FreightTrain: Arrived
Baseado em: Golang By Example

Mediator em outras linguagens

Padrões de Projeto: Mediator em Java Padrões de Projeto: Mediator em C# Padrões de Projeto: Mediator em C++ Padrões de Projeto: Mediator em PHP Padrões de Projeto: Mediator em Python Padrões de Projeto: Mediator em Ruby Padrões de Projeto: Mediator em Swift Padrões de Projeto: Mediator em TypeScript