봄맞이 세일
중재자

Go로 작성된 중재자

중재자는 행동 디자인 패턴이며 프로그램의 컴포넌트들이 특수 중재자 객체를 통하여 간접적으로 소통하게 함으로써 해당 컴포넌트 간의 결합도를 줄입니다.

중재자는 개별 컴포넌트들을 편집, 확장 및 재사용하는 것을 쉽게 만드는데, 그 이유는 이들이 더 이상 수십 개의 다른 클래스들에 의존하지 않기 때문입니다.

개념적인 예시

중재자 패턴의 좋은 예시는 기차역 교통 시스템입니다. 두 열차는 플랫폼의 가용성을 위해 서로 통신하지 않습니다. 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

다른 언어로 작성된 중재자

C#으로 작성된 중재자 C++로 작성된 중재자 자바로 작성된 중재자 PHP로 작성된 중재자 파이썬으로 작성된 중재자 루비로 작성된 중재자 러스트로 작성된 중재자 스위프트로 작성된 중재자 타입스크립트로 작성된 중재자