go ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ• ์ค‘ functional options pattern ์„ ๊ฐ„๋‹จํ•œ ์‹ค์Šต ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์†Œ๊ฐœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

functional option ์€ ํ•จ์ˆ˜/๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ• ๋•Œ ๊ฐ€๋ณ€์ ์ธ ์˜ต์…˜์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

ํ•จ์ˆ˜/๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์žํ• ๋•Œ, ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์ผ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

  1. default parameter ๋ฅผ ์„ค์ •ํ•˜๊ณ ์‹ถ๋‹ค.
  2. optionalํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€๋ณ€์ ์œผ๋กœ ์„ค์ •ํ•˜๊ณ ์‹ถ๋‹ค.

๊ตฌํ˜„ ๋ฐฉ๋ฒ•

  1. optional ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ ์—ญํ• ์„ ํ•ด์ฃผ๋Š” option struct ๋ฅผ ์„ ์–ธ
  2. ์œ„์˜ struct ๋ฅผ ํฌ์ธํ„ฐ ์ฐธ์กฐํ•˜์—ฌ ๊ฐ’์„ ์„ค์ •ํ•ด์ฃผ๋Š” functional options ์ž‘์„ฑ
  3. ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•˜๋Š” ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ณ์— ๊ฐ€๋ณ€์ธ์ž functional options ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์„ค์ •ํ•˜์—ฌ ๊ตฌํ˜„

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ ์ฝ”๋“œ

์˜ˆ๋ฅผ๋“ค์–ด ์™ธ์ถœ์„ ํ•˜๊ณ ์‹ถ์€ ์ €๋Š” GoOut() ์ด๋ผ๋Š” function ์„ ์ˆ˜ํ–‰ํ•˜๊ณ ์‹ถ์Šต๋‹ˆ๋‹ค. GoOut() ์„ ํ• ๋•Œ๋Š” muffler, coat ๋ฅผ ์ž…๊ณ ๋‚˜๊ฐ€๋ฉด ์ข‹์„๊ฑฐ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด muffler, coat ๋ฅผ ์ž…๊ณ ๋‚˜๊ฐˆ์ง€ ๊ฒฐ์ •ํ•˜๋Š” bool ํ”Œ๋ž˜๊ทธ๋“ค์„ optional ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ€์ง„๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1. option struct ์„ค์ •

๊ทธ๋ž˜์„œ muffler, ์™€ coat ๋ผ๋Š” bool field ๋ฅผ ๊ฐ€์ง€๋Š” GoOutOption ๋ผ๋Š” struct๋ฅผ ์„ ์–ธํ•ด์ค๋‹ˆ๋‹ค. ํ•ด๋‹น struct ๋Š” ์ด์ œ ๊ตฌํ˜„ํ•˜๊ณ ์žํ•˜๋Š” GoOut() function ์˜ optional ํ•œ parameter ๋ฆฌ์ŠคํŠธ๋กœ์จ์˜ ์—ญํ• ์„ ํ•˜๋Š” option struct ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

type GoOutOption struct{
  muffler bool
  coat bool
  
  ... // ๋” ์ถ”๊ฐ€ ํ•˜๊ณ  ์‹ถ์€ parameter ๋“ค์„ field ๋กœ ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
}

2. functional options ์ž‘์„ฑ

GoOutOption ์˜ muffler ์— ์ ‘๊ทผํ•˜์—ฌ ๊ฐ’์„ ์„ค์ •ํ•ด์ฃผ๋Š” function ์„ ๋ฆฌํ„ดํ•ด์ค๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฆฌํ„ด ๋˜๋Š” func(option *GoOutOption)์ด functional option ์ด ๋ฉ๋‹ˆ๋‹ค.

coat ์˜ ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์ž‘์„ฑํ•ด์ค๋‹ˆ๋‹ค.

func WithMuffler(isEnabled bool){
  return func(option *GoOutOption){ 
    option.muffler = isEnabled
  }
}

func WithCoat(isEnabled bool){
  return func(option *GoOutOption){ 
    option.muffler = isEnabled
  }
}

3. ๊ฐ€๋ณ€์ธ์ž functional options ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์„ค์ •ํ•˜์—ฌ ๊ตฌํ˜„

์ €๋Š” coat ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž…๊ณ  ๋‚˜๊ฐ€๊ณ  muffler ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž…๊ณ  ๋‚˜๊ฐ€์ง€ ์•Š๋Š” ์„ค์ •์„ default ๋กœ ์ฃผ๋˜ optional ํ•˜๊ฒŒ ์„ค์ •ํ•˜๊ณ ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‚ด๋ถ€์ ์œผ๋กœ GoOutOption ๋ฅผ ๊ฐ€์ง€๊ณ , coat ๋Š” default ๊ฐ’์ด true ์ด๊ณ  muffler ๋Š” false ๊ฐ€ ๋˜๋„๋ก GoOut() ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ functional option ์ธ func(option *GoOutOption) ๋ฅผ ๊ฐ€๋ณ€์ธ์ž๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€๋ณ€์ ์œผ๋กœ ๊ฐ€์ง€๋Š” ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

func GoOut(optFuncs ...func(option *GoOutOption)){
  
  //1.์—์„œ ์„ ์–ธํ•œ option struct ๊ฐ’์„ default ๊ฐ’์œผ๋กœ ์„ค์ •
  option := GoOutOption{ 
    coat : true 
    muffler: false
  }
  
  //option struct ๊ฐ’์„ ์„ค์ •ํ•ด์ฃผ๋Š” ๊ฐ€๋ณ€์ธ์ž functional options ์ˆ˜ํ–‰
  for i:= range optFuncs{
    optFuncs[i](&option) 
  }

  //GoOut~
}

์ด์ œ GoOut() ์„ ์ˆ˜ํ–‰ํ• ๋•Œ functional options ์„ ๊ฐ€๋ณ€์ ์œผ๋กœ ๋„˜๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๋ฐ–์œผ๋กœ ๋‚˜๊ฐˆ ๋•Œ coat ์™€ Muffler ๋ฅผ ๋‘๋ฅด๊ณ  ๋‚˜๊ฐ„๋‹ค.
GoOut(WithMuffler(true))

// ๋ฐ–์œผ๋กœ ๋‚˜๊ฐˆ๋•Œ coat ๋ฅผ ์ž…์ง€ ์•Š๊ณ  ๋‚˜๊ฐ„๋‹ค.
GoOut(WithCoat(false))

// ๋ฐ–์œผ๋กœ ๋‚˜๊ฐˆ ๋•Œ coat ๋งŒ ์ž…๊ณ  ๋‚˜๊ฐ„๋‹ค.
GoOut()

๋‹ค๋ฅธ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„๋„ ์œ„์— ์–ธ๊ธ‰๋“œ๋ฆฐ 1~3 ์˜ ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฉด ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

golang option pattern ๊ด€๋ จ ๊ธ€