빌더패턴에 대해 알아보기 위해 서칭해본 결과 이 패턴은 Gof에서의 설명과 Effective Java 에서의 설명 다르다.
일반적으로 우리가 알고 있는 빌더 패턴은 Effective Java 설명된 것이다.
그래서 Effective Java에서 설명된 빌더 패턴과 Gof에서 설명 된 빌터 패턴을 비교해보자.
Effective Java에서 소개 된 빌더 패턴
객체 생성을 유연하게 하기 위한 패턴이다. 생성 인자가 많거나 생성자에 매개변수가 많을 때 빌터 패턴을 사용하면 유용하다.
class CustomerBuilder
{
private string _name;
private string _address;
private string _birth;
private string _email;
private int _height;
private int _weight;
public CustomerBuilder setName(string name)
{
_name = name;
return this;
}
public CustomerBuilder setAddress(string address)
{
_address = address;
return this;
}
public CustomerBuilder setBirth(string birth)
{
_birth = birth;
return this;
}
public CustomerBuilder setEmail(string email)
{
_email = email;
return this;
}
public CustomerBuilder setHeight(int height)
{
_height = height;
return this;
}
public CustomerBuilder setWeight(int weight)
{
_weight = weight;
return this;
}
public Customer build()
{
Customer customer = new Customer(_name, _address, _birth, _email, _height, _weight);
return customer;
}
}
class Customer
{
private string _name;
private string _address;
private string _birth;
private string _email;
private int _height;
private int _weight;
public override string ToString()
{
return $"name: {_name}, address: {_address}, birth: {_birth}, email: {_email}, height: {_height}, weight: {_weight}";
}
public Customer(string name, string address, string birth, string email, int height, int weight)
{
_name = name;
_address = address;
_birth = birth;
_email = email;
_height = height;
_weight = weight;
}
}
static void Main(string[] args)
{
var customer = new CustomerBuilder().setName("눈누난나")
.setBirth("1900.01.01")
.build();
Console.WriteLine(customer);
}

GoF 에서 설명 된 빌더 패턴
빌더패턴은 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 과정에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다.
클라이언트 코드에서 필요한 객체를 직접 생성하는 대신, 그 전에 필수 인자들을 전달하여 빌더 객체를 만든 뒤, 빌더 객체에 정의된 설정 메서드를 호출하여 인스턴스를 생성하는 것이다.

▷ Builder : 인터페이스
▷ ConcreteBuilder : 빌터 인터페이스 구현체
▷ Director : Builder를 사용해 객체를 생성
▷ Product : Director가 Builder로 만들어낸 결과물
Builder는 부품을 만들고, Director는 빌더가 만든 부품을 조합해 제품을 만들는 것으로 예시를 들 수 있다.
시나리오)
피자 가게에서 웨이터가 피자 주문을 받는다. 웨이터가 주문 받은 내용을 주방에 전달한다.
주방에서는 주문 받은 피자를 만든다.
이때 웨이터가 주문을 것은 Builder와 연결해주는 Director 역할이고 주방에서 피자를 만드는 것은 Builder, ConcreteBuilder의 역할이다.
위의 시나리오 대한 클래스 다이어그램은 아래와 같다.

class Pizza
{
string dough;
string sauce;
string topping;
public Pizza() { }
public void SetDough(string d)
{
dough = d;
}
public void SetSauce(string s)
{
sauce = s;
}
public void SetTopping(string t)
{
topping = t;
}
}
class CheesePizzaBuilder : PizzaBuilder
{
public override void BuildDough()
{
pizza.SetDough("반죽을 빚자");
}
public override void BuildSauce()
{
pizza.SetSauce("치즈에 어울리는 토마토 소스를 슥슥슥");
}
public override void BuildTopping()
{
pizza.SetTopping("짭쪼름한 피자를 솔솔솔");
}
}
abstract class PizzaBuilder
{
protected Pizza pizza;
public PizzaBuilder() { }
public Pizza GetPizza()
{
return pizza;
}
public void CreatNewPizza()
{
pizza = new Pizza();
}
public abstract void BuildDough();
public abstract void BuildSauce();
public abstract void BuildTopping();
}
class Waiter
{
private PizzaBuilder pizzaBuilder;
public void SetPizzaBuilder(PizzaBuilder pd)
{
pizzaBuilder = pd;
}
public Pizza GetPizza()
{
return pizzaBuilder.GetPizza();
}
public void ConstructPizza()
{
pizzaBuilder.CreatNewPizza();
pizzaBuilder.BuildDough();
pizzaBuilder.BuildSauce();
pizzaBuilder.BuildTopping();
}
}
static void Main(string[] args)
{
Waiter waiter = new Waiter();
CheesePizzaBuilder cheesePizzaBuilder = new CheesePizzaBuilder();
HawaiianPizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
waiter.SetPizzaBuilder(cheesePizzaBuilder);
waiter.ConstructPizza();
Pizza pizza = waiter.GetPizza();
}

생성자와 표현자가 확실하게 분리되어 있음을 확인 할 수 있다.
'STUDY > Design Pattern' 카테고리의 다른 글
| 어댑터 패턴 (Adapter pattern) (0) | 2022.11.27 |
|---|---|
| 단일체 패턴(Singleton Pattern) (0) | 2022.11.27 |
| 원형 패턴 (Prototype Pattern) (0) | 2022.11.27 |
| 팩토리 메소드 패턴 (Factory Method Pattern) (0) | 2022.11.27 |
| 추상 팩토리 패턴 (Abstract Factory Pattern) (0) | 2022.11.27 |