Friend spotlight!
Whimsical Animations course
Friend spotlight!
NEW Whimsical Animations course
Friend spotlight! NEW Whimsical Animations course
huge discount only this week
Friend spotlight! Want to make your project stand out? NEW Whimsical Animations course huge discount only this week
Mediator

Mediator を Go で

Mediator 振る舞いに関するデザインパターンの一つで プログラムのコンポーネント間の通信を特別なメディエーター・オブジェクトを通して行うことで 結合を疎にします

Mediator により 個々のコンポーネントは 何十ものクラスへの依存がなくなるため 変更 拡張 再利用が容易になります

概念的な例

Mediator パターンの素晴らしい例は 鉄道駅での交通システムです 二つの列車同士は決してプラットホームが使えるかどうかについて通信しません station­Manager 駅長 がメディエーターの役を果たし 到着する列車一つにだけプラットホームを使えるようにし 残りの列車には待ってもらいます 出発列車は駅に連絡をし 待ち行列の次の列車の到着が許されます

train.go: コンポーネント

package main

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

passengerTrain.go: 具象コンポーネント

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: 具象コンポーネント

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: メディエーター・インターフェース

package main

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

stationManager.go: 具象メディエーター

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: クライアント・コード

package main

func main() {
	stationManager := newStationManger()

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

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

output.txt: 実行結果

PassengerTrain: Arrived
FreightTrain: Arrival blocked, waiting
PassengerTrain: Leaving
FreightTrain: Arrival permitted
FreightTrain: Arrived

他言語での Mediator

Mediator を C# で Mediator を C++ で Mediator を Java で Mediator を PHP で Mediator を Python で Mediator を Ruby で Mediator を Rust で Mediator を Swift で Mediator を TypeScript で