1. Builder Pattern
Person 객체를 예로 들어보자
type Person struct {
name string
age int
job string
height float32
weight float32
}
func NewPerson(name string, age int, job string, height float32, weight float32) *Person {
return &Person{
name,
age,
job,
height,
weight,
}
}
func main() {
p := NewPerson("홍길동", 22, "developer", 177.2, 72.9)
}
위처럼 모든 정보를 입력하지 않아도 될때도 있고, 가독성도 좋지않으며 parameter의 순서도 맞춰주어야한다.
또 객체에 새로운 정보가 추가된다면 NewPerson()을 계속 수정해주어야 한다.
이를 해결하기 위해 Builder를 이용해보자.
type Person struct {
name string
age int
job string
height float32
weight float32
}
type PersonBuilder struct {
person *Person
}
func NewPersonBuilder() *PersonBuilder {
return &PersonBuilder{&Person{}}
}
func (b *PersonBuilder) Name(name string) *PersonBuilder {
b.name = name
return b
}
func (b *PersonBuilder) Age(age int) *PersonBuilder {
b.age = age
return b
}
func (b *PersonBuilder) Job(job string) *PersonBuilder {
b.job = job
return b
}
func (b *PersonBuilder) Height(height float32) *PersonBuilder {
b.height = height
return b
}
func (b *PersonBuilder) Weight(weight float32) *PersonBuilder {
b.weight = weight
return b
}
func (b *PersonBuilder) Build() *Person {
return b.person
}
func main() {
pb := NewPersonBuilder().
Age(22).
Height(177.2).
Weight(72.9).
Name("홍길동").
Job("developer")
p := pb.Build()
}
순서를 맞추지 않아도 되고 가독성도 좋아졌다.
2. 함수형으로 Builder Pattern 사용
type Person struct {
name string
age int
job string
height float32
weight float32
}
type modPerson func(*Person)
type PersonBuilder struct {
actions []modPerson
}
func (b *PersonBuilder) Name(name string) *PersonBuilder {
b.actions = append(b.actions, func(p *Person) {
p.name = name
})
return b
}
func (b *PersonBuilder) Age(age int) *PersonBuilder {
b.actions = append(b.actions, func(p *Person) {
p.age = age
})
return b
}
func (b *PersonBuilder) Job(job string) *PersonBuilder {
b.actions = append(b.actions, func(p *Person) {
p.job = job
})
return b
}
func (b *PersonBuilder) Height(height float32) *PersonBuilder {
b.actions = append(b.actions, func(p *Person) {
p.height = height
})
return b
}
func (b *PersonBuilder) Weight(weight float32) *PersonBuilder {
b.actions = append(b.actions, func(p *Person) {
p.weight = weight
})
return b
}
func (b *PersonBuilder) Build() *Person {
p := &Person{}
for _, action := range b.actions {
action(p)
}
return p
}
func NewPersonBuilder() *PersonBuilder {
return &PersonBuilder{}
}
func main() {
pb := NewPersonBuilder().
Age(22).
Height(177.2).
Weight(72.9).
Name("홍길동").
Job("developer")
p := pb.Build()
}