PHpullh
학습 라이브러리/Go/이벤트 시스템

GO · 패턴

이벤트 시스템

Pub/Sub 패턴으로 컴포넌트 간 느슨한 결합을 구현합니다. 이벤트 발행과 구독을 분리합니다.

패턴고급event-buspub-subloose-couplingasync

핵심 설명

Pub/Sub 패턴으로 컴포넌트 간 느슨한 결합을 구현합니다. 이벤트 발행과 구독을 분리합니다.

Go code

package main

import (
	"fmt"
	"sync"
)

type Event struct {
	Type string
	Data any
}

type Handler func(Event)

type EventBus struct {
	mu       sync.RWMutex
	handlers map[string][]Handler
}

func NewEventBus() *EventBus {
	return &EventBus{handlers: make(map[string][]Handler)}
}

func (eb *EventBus) Subscribe(eventType string, h Handler) {
	eb.mu.Lock()
	defer eb.mu.Unlock()
	eb.handlers[eventType] = append(eb.handlers[eventType], h)
}

func (eb *EventBus) Publish(evt Event) {
	eb.mu.RLock()
	defer eb.mu.RUnlock()
	for _, h := range eb.handlers[evt.Type] {
		go h(evt) // 비동기 처리
	}
}

func main() {
	bus := NewEventBus()

	bus.Subscribe("user.created", func(e Event) {
		fmt.Println("이메일 발송:", e.Data)
	})
	bus.Subscribe("user.created", func(e Event) {
		fmt.Println("로그 기록:", e.Data)
	})
	bus.Subscribe("order.placed", func(e Event) {
		fmt.Println("재고 확인:", e.Data)
	})

	bus.Publish(Event{Type: "user.created", Data: "Gopher"})
	bus.Publish(Event{Type: "order.placed", Data: "주문#100"})

	// 비동기 핸들러 완료 대기
	fmt.Scanln()
}

학습 팁

이벤트 핸들러를 고루틴으로 실행하면 발행자가 블로킹되지 않습니다. 에러 처리는 핸들러 내부에서 수행하세요.

주의할 점

이벤트 핸들러에서 패닉이 발생하면 해당 고루틴만 종료됩니다. 프로덕션에서는 recover로 보호하세요.

자주 묻는 질문

이벤트 시스템란 무엇인가요?

Pub/Sub 패턴으로 컴포넌트 간 느슨한 결합을 구현합니다. 이벤트 발행과 구독을 분리합니다.

이벤트 시스템 학습 시 주의할 점은 무엇인가요?

이벤트 핸들러에서 패닉이 발생하면 해당 고루틴만 종료됩니다. 프로덕션에서는 recover 로 보호하세요.