빌더패턴은 복잡한 객체의 생성을 동일한 절차에서 서로 다른 결과를 만들어 낼수 있는 패턴이다.
자 예를들어 우리가 스타크래프트를 한다고 할때
우리는 종족을 저그,프로토스,테란 중 하나를 선택하는데 이 객체의 생성을 동일한 절차 즉 버튼하나만으로 그걸 구분해낸다.
그리고 그 종족을 고르면 우리는 전혀 다른 종족으로 플레이를 할수 있는것이다.
빌더패턴에서 중요한 Director 클래스가 있는데 이게 게임을 플레이하는 나(Player = Director) 라고 생각하면된다.
내(Director) 가 빌더패턴을 이용해서 종족이라는 빌더(Zerg,Protoss,Terran)를 정의한후
플레이(메서드구현)을 하면 그게 빌드패턴이 되는거다.
이번에도 스타크래프트를 예로 빌더패턴을 구현해보겠다.

위와 같이 빌더 인터페이스를 정의하고 그 빌더를 임베딩하는 Player 를 정의한다.
지상 유닛을 생성하기 위한 GroundBuilding()
공중 유닛을 생성하기 위한 AirBuilding()
빌더는 종족에 따라 빌더가 만들어내는 값은 다 다르다.

게임을 하려면 아이디가 있어야 하기에 Player 를 초기화 하는 함수를 만들었다.

SetPlayer() 는 다음판을 할때 또 종족을 고를수 있게 한다.
CreateBuilding() 은 Player 에 임베디드된 빌더의 메서드를 호출함으로써
각 종종에 해당하는 건물을 만들수 있다.
즉 우리는 종족마다 다른 빌더들을 가지고 있는 셈이 된다.

모든 건물을 다 적기엔 너무 많아서 대표적인 스포닝풀, 히드라덴 , 스파이어를 가지고있는
저그 구조체와 위에서 정의한 Builder 인터페이스에 있는 메서드를 구현해줬다.
테란과 프로토스도 위와같이 동일하게 작성하면 된다.
코드가 너무 길어지니 아래에 복사할수 있는 전체코드를 삽입해 놓겠다.

메인 함수에서 호출 하는걸 보면 임요환 , 김택용 , 홍진호가
모두 같은 Director 를 가지고 다른 Builder 들을 호출하는 걸 볼수 있다.
그리고 Director 의 CreateBuilding() 은 각각의 빌더에 대한 메서드를 호출하기 때문에
각 종족에 맞는 건물들이 다양하게 지어지게 된다.

빌더 패턴은 실세계에서 감독이 다양한 직원들을 고용하고 그 직원들은 각자 맡은 일만 할수있고
또 감독은 그 직원들을 해고할수 느낌이랄까
아래에는 전체코드다.
package main
import (
"fmt"
"time"
)
type Builder interface{
GroundBuilding()
AirBuilding()
}
type Player struct{
builder Builder
}
func NewPlayer(b Builder) *Player {
return &Player{
builder : b,
}
}
func (p *Player) SetPlayer(b Builder) {
p.builder = b
}
func(p *Player) CreateBuilding() {
fmt.Println("지상 건물 건설")
time.Sleep(time.Second)
p.builder.GroundBuilding()
fmt.Println("공중 건물 건설")
time.Sleep(time.Second)
p.builder.AirBuilding()
}
type Zerg struct {
SpawningPool string
HydraliskDen string
Spire string
}
func (z Zerg) GroundBuilding() {
fmt.Println("스포닝풀 , 히드라덴 짓는중..")
time.Sleep(time.Second)
z.SpawningPool = "spawning pool"
z.HydraliskDen = "hidralisk den"
fmt.Println("스포닝풀 , 히드라덴 완료")
}
func (z Zerg) AirBuilding() {
fmt.Println("스파이어 짓는중..")
time.Sleep(time.Second)
z.Spire = "spire"
fmt.Println("스파이어 완료")
}
type Protoss struct {
GateWay string
Cybernetics string
Stargate string
}
func (p Protoss) GroundBuilding() {
fmt.Println("게이트웨이, 사이버네틱스 코어 짓는중..")
time.Sleep(time.Second)
p.GateWay = "gateway"
p.Cybernetics = "cybernetics"
fmt.Println("게이트웨이, 사이버네틱스 코어 완료")
}
func (p Protoss) AirBuilding() {
fmt.Println("게이트 웨이 짓는중..")
time.Sleep(time.Second)
p.Stargate = "stargate"
fmt.Println("게이트 웨이 완료")
}
type Terran struct {
Barracks string
Factory string
StarPort string
}
func (t Terran) GroundBuilding() {
fmt.Println("배럭 , 팩토리 짓는중..")
time.Sleep(time.Second)
t.Barracks = "barracks"
t.Factory = "factory"
fmt.Println("배럭, 팩토리 완료")
}
func (t Terran) AirBuilding() {
fmt.Println("스타포트 짓는중..")
time.Sleep(time.Second)
t.StarPort = "starport"
fmt.Println("스타포트 완료")
}
func main() {
ImYoHwan := NewPlayer(Terran{})
ImYoHwan.CreateBuilding()
KimTakYong := NewPlayer(Protoss{})
KimTakYong.CreateBuilding()
HongZinHoHongZinHo := NewPlayer(Zerg{})
HongZinHoHongZinHo.CreateBuilding()
}
'Go' 카테고리의 다른 글
네이버 클라우드 플랫폼 카카오톡 알림톡 (golang) (0) | 2022.10.12 |
---|---|
golang 프로토타입패턴(Prototype Pattern with golang) (0) | 2022.08.10 |
golang 상속 (상속아님) (0) | 2022.07.21 |
golang 추상팩토리 패턴(Abstract Factory with golang) (0) | 2022.07.19 |
golang 싱글톤 패턴(Singleton Pattern with golang) (0) | 2022.07.14 |