Kim Seogyu
Backend

Functional Options 패턴을 활용한 Go 설정 관리

Go에서 필수 인자와 선택 옵션을 분리해 생성자 API를 안정적으로 유지하는 방법을 정리합니다.

Published 2025년 12월 30일1 min read197 words

Functional Options 패턴을 활용한 Go 설정 관리

왜 쓰는가

설정 필드가 늘어날수록 생성자 시그니처는 빠르게 깨집니다. Functional Options는 아래 두 가지를 분리해 문제를 줄입니다.

  • 필수값: 생성자 인자로 강제
  • 선택값: With... 옵션으로 오버라이드

기본 형태

type Config struct {
	batchSize int
	timeout   time.Duration
}

type Option func(*Config)

func WithBatchSize(v int) Option {
	return func(c *Config) {
		if v > 0 {
			c.batchSize = v
		}
	}
}

func WithTimeout(v time.Duration) Option {
	return func(c *Config) {
		if v > 0 {
			c.timeout = v
		}
	}
}

func NewWorker(client Client, handler Handler, opts ...Option) *Worker {
	cfg := Config{batchSize: 10, timeout: 5 * time.Second}
	for _, opt := range opts {
		opt(&cfg)
	}
	return &Worker{client: client, handler: handler, cfg: cfg}
}

실무 규칙

  • 필수 의존성(client, handler)은 절대 옵션으로 내리지 않기
  • 옵션 함수에서 유효성 검증 수행
  • 기본값은 생성자 내부에서 한 번만 정의

자주 하는 실수

  • 옵션끼리 충돌 규칙이 없음 (예: timeout 0 허용)
  • 생성자 외부에서 기본값을 중복 관리
  • 모든 값을 옵션으로 처리해 필수값 계약 붕괴

요약

Functional Options는 "유연한 설정" 패턴이 아니라 "생성자 안정성" 패턴입니다. 필수/선택 경계를 명확히 유지하면 API가 오래 버팁니다.

Share

Related Articles

Comments

이 블로그는 제가 알고 있는 것들을 잊지 않기 위해 기록하는 공간입니다.
직접 작성한 글도 있고, AI의 도움을 받아 정리한 글도 있습니다.
정확하지 않은 내용이 있을 수 있으니 참고용으로 봐주세요.

© 2026 Seogyu Kim