겨울 세일!
빌더

Go로 작성된 빌더

빌더는 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인 패턴입니다.

다른 생성 패턴과 달리 빌더 패턴은 제품들에 공통 인터페이스를 요구하지 않습니다. 이를 통해 같은 생성공정을 사용하여 다양한 제품을 생산할 수 있습니다.

개념적인 예시

<0>빌더</0> 패턴은 필요한 제품이 복잡하고 이를 생성하기 위하여 여러 단계가 필요할 때 사용됩니다. 여러 생성 메서드들이 하나의 거대한 생성자보다 간단할 것입니다. 그러나 이러한 다단계 생성 프로세스의 잠재적인 문제는 완성되지 않은 불안정한 제품이 클라이언트에 노출될 수 있다는 점입니다. 빌더 패턴은 제품이 완성될 때까지 해당 제품을 비공개로 유지합니다.

아래 코드에는 다양한 유형의 주택들​(igloo and normal­House)​이 다음 빌더들​(igloo­Buildernormal­Builder)​에 의해 생성되는 것을 볼 수 있습니다. 각 주택 유형은 생성 단계들이 같습니다. 또 선택사항인 디렉터 구조체는 생성 프로세스를 정리하는 데 도움이 됩니다.

iBuilder.go: 빌더 인터페이스

package main

type IBuilder interface {
	setWindowType()
	setDoorType()
	setNumFloor()
	getHouse() House
}

func getBuilder(builderType string) IBuilder {
	if builderType == "normal" {
		return newNormalBuilder()
	}

	if builderType == "igloo" {
		return newIglooBuilder()
	}
	return nil
}

normalBuilder.go: 구상 빌더

package main

type NormalBuilder struct {
	windowType string
	doorType   string
	floor      int
}

func newNormalBuilder() *NormalBuilder {
	return &NormalBuilder{}
}

func (b *NormalBuilder) setWindowType() {
	b.windowType = "Wooden Window"
}

func (b *NormalBuilder) setDoorType() {
	b.doorType = "Wooden Door"
}

func (b *NormalBuilder) setNumFloor() {
	b.floor = 2
}

func (b *NormalBuilder) getHouse() House {
	return House{
		doorType:   b.doorType,
		windowType: b.windowType,
		floor:      b.floor,
	}
}

iglooBuilder.go: 구상 빌더

package main

type IglooBuilder struct {
	windowType string
	doorType   string
	floor      int
}

func newIglooBuilder() *IglooBuilder {
	return &IglooBuilder{}
}

func (b *IglooBuilder) setWindowType() {
	b.windowType = "Snow Window"
}

func (b *IglooBuilder) setDoorType() {
	b.doorType = "Snow Door"
}

func (b *IglooBuilder) setNumFloor() {
	b.floor = 1
}

func (b *IglooBuilder) getHouse() House {
	return House{
		doorType:   b.doorType,
		windowType: b.windowType,
		floor:      b.floor,
	}
}

house.go: 제품

package main

type House struct {
	windowType string
	doorType   string
	floor      int
}

director.go: 디렉터

package main

type Director struct {
	builder IBuilder
}

func newDirector(b IBuilder) *Director {
	return &Director{
		builder: b,
	}
}

func (d *Director) setBuilder(b IBuilder) {
	d.builder = b
}

func (d *Director) buildHouse() House {
	d.builder.setDoorType()
	d.builder.setWindowType()
	d.builder.setNumFloor()
	return d.builder.getHouse()
}

main.go: 클라이언트 코드

package main

import "fmt"

func main() {
	normalBuilder := getBuilder("normal")
	iglooBuilder := getBuilder("igloo")

	director := newDirector(normalBuilder)
	normalHouse := director.buildHouse()

	fmt.Printf("Normal House Door Type: %s\n", normalHouse.doorType)
	fmt.Printf("Normal House Window Type: %s\n", normalHouse.windowType)
	fmt.Printf("Normal House Num Floor: %d\n", normalHouse.floor)

	director.setBuilder(iglooBuilder)
	iglooHouse := director.buildHouse()

	fmt.Printf("\nIgloo House Door Type: %s\n", iglooHouse.doorType)
	fmt.Printf("Igloo House Window Type: %s\n", iglooHouse.windowType)
	fmt.Printf("Igloo House Num Floor: %d\n", iglooHouse.floor)

}

output.txt: 실행 결과

Normal House Door Type: Wooden Door
Normal House Window Type: Wooden Window
Normal House Num Floor: 2

Igloo House Door Type: Snow Door
Igloo House Window Type: Snow Window
Igloo House Num Floor: 1

다른 언어로 작성된 빌더

C#으로 작성된 빌더 C++로 작성된 빌더 자바로 작성된 빌더 PHP로 작성된 빌더 파이썬으로 작성된 빌더 루비로 작성된 빌더 러스트로 작성된 빌더 스위프트로 작성된 빌더 타입스크립트로 작성된 빌더