package main
import (
"fmt"
"strconv"
)
type Color string
type Make string
type Model string
const (
BLUE Color = "blue"
RED = "red"
)
type Car interface {
Drive() string
Stop() string
}
type CarBuilder interface {
TopSpeed(int) CarBuilder
Paint(Color) CarBuilder
Build() Car
}
type carBuilder struct {
speedOption int
color Color
}
func (cb *carBuilder) TopSpeed(speed int) CarBuilder {
cb.speedOption = speed
return cb
}
func (cb *carBuilder) Paint(color Color) CarBuilder {
cb.color = color
return cb
}
func (cb *carBuilder) Build() Car {
return &car{
topSpeed: cb.speedOption,
color: cb.color,
}
}
func New() CarBuilder {
return &carBuilder{}
}
type car struct {
topSpeed int
color Color
}
func (c *car) Drive() string {
return "Driving at speed: " + strconv.Itoa(c.topSpeed)
}
func (c *car) Stop() string {
return "Stopping a " + string(c.color) + " car"
}
func main() {
assembly := New()
sportsCar := assembly.TopSpeed(250).Paint(BLUE).Build()
famillyCar := assembly.TopSpeed(80).Paint(RED).Build()
fmt.Println(sportsCar.Drive())
fmt.Println(sportsCar.Stop())
fmt.Println(famillyCar.Drive())
fmt.Println(famillyCar.Stop())
}
차량 옵션과 기능을 설정하기 위해서 CarBuilder 인터페이스를 준비했다. TopSpeed, Paint 메서드를 이용해서 차량 옵션을 설정할 수 있다. 그리고 차량의 기능인 Drive와 Stop 역시 인터페이스로 구성하기로 했다. 이제 개발자는 TopSpeed와 Paint 메서드를 구현해서 옵션을 설정하고, Drive와 Stop의 구현으로 차량 기능을 만들 수 있다.
현실의 예
빌더패턴은 복잡한 객체의 구성과 표현을 분리해서, 동일한 구성의 프로세스로 다른 표현이 가능하게 한다. 이 패턴은 패스트 푸드 식당에서 아이들의 식사를 만드는데 사용 할 수 있다.
어린이 식사는 주 물품, 부대 아이템, 음료 및 장난감등으로 구성된다. 이때 식사의 구성에 차이가 있을 수는 있지만 동일한 제조 프로세스를 따른다는 것에 유의해야 한다. 고객이 치즈버거를 주문하든 불고기버거를 주문하든 만드는 과정은 동일하다.
Contents
빌더 패턴
해결 방법
- 불필요한 생성자를 만들지 않고 객체를 만들 수 있어야 한다.
- 파라메터의 순서와 상관없이 객체를 만들 수 있어야 한다.
- 파라메터의 단순 입력과 달리, 명시적이고 이해 할 수 있는 수단을 마련해야 한다. 
헷갈리지 않게 명확히 객체를 만들 수 있게 하자는게 요지다.간단 구현
package main import ( "fmt" "strconv" ) const ( BLUE string = "blue" RED = "red" ) type car struct { Speed int Color string } func NewBuilder() *car { return &car{} } func (c *car) TopSpeed(speed int) *car { c.Speed = speed return c } func (c *car) Painting(color string) *car { c.Color = color return c } func (c *car) Drive() string { return "Driving at speed: " + strconv.Itoa(c.Speed) } func (c *car) Stop() string { return "Stopping a " + string(c.Color) + " car" } func main() { sportsCar := NewBuilder().Painting(BLUE).TopSpeed(250) fmt.Println(sportsCar.Drive()) fmt.Println(sportsCar.Stop()) famillyCar := NewBuilder().Painting(RED).TopSpeed(100) fmt.Println(famillyCar.Drive()) fmt.Println(famillyCar.Stop()) }개선해보자.
package main import ( "fmt" "strconv" ) type Color string type Make string type Model string const ( BLUE Color = "blue" RED = "red" ) type Car interface { Drive() string Stop() string } type CarBuilder interface { TopSpeed(int) CarBuilder Paint(Color) CarBuilder Build() Car } type carBuilder struct { speedOption int color Color } func (cb *carBuilder) TopSpeed(speed int) CarBuilder { cb.speedOption = speed return cb } func (cb *carBuilder) Paint(color Color) CarBuilder { cb.color = color return cb } func (cb *carBuilder) Build() Car { return &car{ topSpeed: cb.speedOption, color: cb.color, } } func New() CarBuilder { return &carBuilder{} } type car struct { topSpeed int color Color } func (c *car) Drive() string { return "Driving at speed: " + strconv.Itoa(c.topSpeed) } func (c *car) Stop() string { return "Stopping a " + string(c.color) + " car" } func main() { assembly := New() sportsCar := assembly.TopSpeed(250).Paint(BLUE).Build() famillyCar := assembly.TopSpeed(80).Paint(RED).Build() fmt.Println(sportsCar.Drive()) fmt.Println(sportsCar.Stop()) fmt.Println(famillyCar.Drive()) fmt.Println(famillyCar.Stop()) }현실의 예
참고
Recent Posts
Archive Posts
Tags