이번에는 Builder Pattern을 정리하고자 한다.
해당 패턴은 객체의 생성과정이 복잡할 경우에 사용하여 이를 간단하게 만들어 준다.
이때, 생성과정이 복잡할 수 있는 경우는 매우 다양하여 작성자의 판단이 중요하다.
예를 들어, 하나의 오브젝트를 생성할 때, 여러 개의 argument가 필요할 때 해당 패턴을 사용하기에 적합하다.
객체의 생성 argument가 복잡하고 많은 경우라서 Builder 메소드를 기준점(API)으로 정하고 이를 사용자가 쉽게 사용할 수 있도록 한다.
예시를 들어보자.
피자를 판매하고자 한다. 이때, 다양한 종류의 피자들을 한번에 생성하고자 한다.
해당 문제에 관한 코드를 Builder Pattern을 이용해 짜 보면 다음과 같다.
# Product 클래스
class Pizza:
def __init__(self):
self.size = None
self.cheese = False
self.pepperoni = False
self.bacon = False
def pizza_state(self):
print("size: {}, cheese: {}, pepperoni: {}, bacon: {}".format(self.size, self.cheese, self.pepperoni, self.bacon))
# API -> for 문으로 반복 가능
class PizzaBuilder: # 인터페이스
def set_size(self, size):
pass
def add_cheese(self):
pass
def add_pepperoni(self):
pass
def add_bacon(self):
pass
def get_pizza(self):
# 종류마다 builder를 만들어 탬플릿으로 만듦
class MargheritaBuiler(PizzaBuilder): # concreteBuilder
def __init__(self):
self.pizza = Pizza()
def set_size(self, size):
self.pizza.size = size
return self
def add_cheese(self):
self.pazza.cheese = True
return self
def add_pepperoni(self):
# 마르게리따에는 페퍼로니가 들어가지 않는다.
pass
def add_bacon(self):
# 마르게리따에는 베이컨이 들어가지 않는다.
pass
def build(self):
return self.pizza
class MeatLoverBuilder(PizzaBuilder): # concreteBuilder
def __init__(self):
self.pizza = Pizza()
def set_size(self, size):
self.pizza.size = size
return self
def add_cheese(self):
self.pizza.cheese = True
return self
def add_pepperoni(self):
self.pizza.pepperoni = True
return self
def add_bacon(self):
self.pizza.bacon = True
return self
def build(self):
return self.pizza
# Director
class PizzaDirector:
def __init__(self, builder):
self.builder = builder
def construct(self, size = "Medium"):
self._builder.set_size(size)
self._builder.add_cheese()
self._builder.add_pepperoni()
self._builder.add_bacon()
return self._builder.build()
margherita_builder = MargheritaBuilder()
director = PizzaDirector(margherita_builder)
margherita_pizza = director.construct(size="Large")
print("Margherita Pizza:", margherita_pizza)
meat_lover_builder = MeatLoverBuilder()
director = PizzaDirector(meat_lover_builder)
meat_lover_pizza = director.construct(size="Large")
print("Meat Lover Pizza:", meat_lover_pizza)