 
                Mediator を Go で
Mediator は、 振る舞いに関するデザインパターンの一つで、 プログラムのコンポーネント間の通信を特別なメディエーター・オブジェクトを通して行うことで、 結合を疎にします。
Mediator により、 個々のコンポーネントは、 何十ものクラスへの依存がなくなるため、 変更、 拡張、 再利用が容易になります。
概念的な例
Mediator パターンの素晴らしい例は、 鉄道駅での交通システムです。 二つの列車同士は決してプラットホームが使えるかどうかについて通信しません。 stationManager (駅長) がメディエーターの役を果たし、 到着する列車一つにだけプラットホームを使えるようにし、 残りの列車には待ってもらいます。 出発列車は駅に連絡をし、 待ち行列の次の列車の到着が許されます。 
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