๋ฐ์ํ
Builder Pattern
Builder ํจํด์ ๊ฐ์ฒด ์์ฑ ํจํด ์ค ํ๋๋ก, ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ๋จ๊ณ์ ์ผ๋ก ๊ตฌ์ฑํ ์ ์๋๋ก ํ๋ ํจํด์ ๋๋ค.
- Object์ ์์ฑ๊ณผ์ ์ด ๋ณต์กํ ๋ ์ด๋ฅผ ๊ฐ๋จํ๊ฒ ๋ง๋ค์ด์ค๋๋ค.
- ์์ฑ๊ณผ์ ์ด ๋ณต์กํ ์ ์๋ ์ฌ๋ฌ ๊ฒฝ์ฐ๋ ๋งค์ฐ ๋ค์ํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด ํ๋์ Object๋ฅผ ์์ฑ์, ์ฌ๋ฌ๊ฐ์ argument๊ฐ ํ์ํ ๋ Builder Pattern์ด ์ฝ๊ฒ ๋ง๋ค์ด ์ค ์ ์์ต๋๋ค.
ํต์ฌ ๊ฐ๋
- Builder ์ธํฐํ์ด์ค: ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑํ๋ ๊ฐ ๋จ๊ณ๋ฅผ ์ ์ํฉ๋๋ค.
- Concrete Builder ํด๋์ค: Builder ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ฌ, ๊ฐ ๋จ๊ณ๋ฅผ ๊ตฌ์ฒด์ ์ผ๋ก ์ ์ํฉ๋๋ค.
- Director: Builder ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด ์์ฑ์ ์์๋ฅผ ์ ์ํฉ๋๋ค. ์์ฑ ๊ณผ์ ์ ์ ์ด๋ฅผ ๋ด๋นํฉ๋๋ค.
- Product: ์ต์ข ์ ์ผ๋ก ์์ฑ๋ ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ๋ํ๋ ๋๋ค.
์ฅ์
- ๋ณต์กํ ๊ฐ์ฒด ์์ฑ์ ๋ถ๋ฆฌ: ๊ฐ์ฒด ์์ฑ ์ฝ๋๋ฅผ ์ ํ์ ํํ ์ฝ๋์ ๋ถ๋ฆฌํ ์ ์์ต๋๋ค.
- ์ ์ฐํ ๊ฐ์ฒด ์์ฑ: ๋ค์ํ ๊ตฌ์ฑ ์ต์ ์ ํตํด ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
- ๊ฐ์ฒด ์์ฑ์ ๋จ๊ณ์ ์ ๊ทผ: ๊ฐ์ฒด๋ฅผ ๋จ๊ณ๋ณ๋ก ์์ฑํ ์ ์์ด, ์์ฑ ๊ณผ์ ์ ์ ์ฐ์ฑ์ด ๋์์ง๋๋ค.
๋จ์
- ๋ณต์ก์ฑ ์ฆ๊ฐ: ํจํด์ ๊ตฌํํ๋ ๋ฐ ํ์ํ ํด๋์ค๊ฐ ๋ง์์ ธ ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์์ต๋๋ค.
- ์ผ๊ด๋ ์ธํฐํ์ด์ค ์๊ตฌ: ๋ชจ๋ Builder๊ฐ ๋์ผํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ฏ๋ก, ์๋ก์ด Builder๋ฅผ ์ถ๊ฐํ๋ ์์ ์ด ๋ฒ๊ฑฐ๋ก์ธ ์ ์์ต๋๋ค.
Example.1 (๊ณ ์์ด ์์ฑ)
ํ๋ฒ ๊ณ ์์ด์ ์์ฑ ๊ณผ์ ์ด ๋งค์ฐ ๋ณต์กํ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
class Cat:
def _init_ (self,height,weight,color):
self.height = height
self.weight = weight
self.color = color
def print(self):
return print(f"Height: {self.height}, Weight: {self.weight}, Color: {self.color}")
# API
class catBuilder:
def _init_(self):
self.height = None
self.weight = None
self.color = None
def set_height(self, height):
self.height = height
return self
def set_weight(self, weight):
self.weight = weight
return self
def set_color(self, color):
self.color = color
return self
def build(self):
cat = Cat(self.height, self.weight, self.color)
return cat
# Concrete
class WhiteCatBuilder(catBuilder):
def _init_(self):
self.color = "white"
class BlackCatBuilder(catBuilder):
def _init_(self):
self.color = "black"
cat_builder = Cat()
cat_builder.set_height(30)
cat_builder.set_weight(7)
cat_builder.set_color("Black")
cat = cat_builder.build()
cat.print()
Example.2 (Pizza Case 1: Product)
ํผ์๋ฅผ ํ๋งคํ๊ณ ์ ํ ๋, ๋ค์ํ ์ข ๋ฅ์ ํผ์๋ค์ ํ๋ฒ์ ์์ฑํ๊ณ ์ ํฉ๋๋ค.
- 4๊ฐ์ ์ค์ ์ด ํ์ํ ๋ณ์๋ค
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 & Concrete Builder
# API
class PizzaBuilder:
def set_size(self, size):
pass
def add_cheese(self):
pass
def add_pepperoni(self):
pass
def add_bacon(self):
pass
def build(self):
pass
# Concrete
class Margheritabuilder(PizzaBuilder):
def _init_(self):
self.pizza = Pizza()
def set_size(self, size):
self.pizza.size = size
def add_cheese(self):
self.pizza.cheese = True
def add_pepperoni(self):
pass
def add_bacon(self):
pass
def build(self):
return self.pizza
# Concrete
class MeatLoversBuilder(PizzaBuilder):
def _init_(self):
self.pizza = Pizza()
def set_size(self, size):
self.pizza.size = size
def add_cheese(self):
self.pizza.cheese = True
def add_pepperoni(self):
self.pizza.pepperoni = True
def add_bacon(self):
self.pizza.bacon = True
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_lovers_builder = MeatLoversBuilder()
director = PizzaDirector(meat_lovers_builder)
meat_lovers_pizza = director.construct(size="Large")
print("Meat Lovers Pizza", meat_lovers_pizza)
Example.3 (Pizza Case 2: Product)
ํผ์๋ฅผ ํ๋งคํ๊ณ ์ ํ ๋, ๋ค์ํ ์ข ๋ฅ์ ํผ์๋ค์ ๋ฏธ๋ฆฌ ์ค์ ๋ argument๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑํ๊ณ ์ ํฉ๋๋ค.
- 5๊ฐ์ ์ค์ ์ด ํ์ํ ๋ณ์๋ค
class Pizza:
def _init_(self):
self.size = None
self.cheese = False
self.pepperoni = False
self.bacon = False
self.vegetables = []
def pizza_state(self):
print("size: {}, cheese: {}, pepperoni: {}, bacon: {}, vegetables: {}".format(self.size, self.cheese, self.pepperoni, self.bacon, self.vegetables))
# ๋ณ๋์ Builder API๋ฅผ ๋์ง ์์
class PizzaBuilder:
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 add_vegetables(self, vegetables):
self.pizza.vegetables = vegetables
return self
def build(self):
finished_pizza = self.pizza
self.reset()
return finished_pizza
# ์ข
๋ฅ๋ณ ํผ์์ ๋ํ ์ฝ๋๋ฅผ ์ง์ ์
๋ ฅํด์ผํจ
class PizzaDirector:
def _init_(self, builder):
self.builder = builder
def prepare_marinara(self):
return self.builder.set_size("Large").add_cheese().build()
def prepare_meat_lovers(self):
return self.builder.set_size("Large").add_cheese().add_pepperoni().add_bacon().build()
def prepare_vegetarian(self):
self.builder.reset()
return self.builder.set_size("Large").add_cheese().add_vegetables(["Bell papers", "Olives", "Onions"]).build()
# ์ฌ์ฉ ์์ - ์ข
๋ฅ๋ณ ํผ์์ ๋ํ ์ฝ๋๋ฅผ ์ง์ ์
๋ ฅํด์ผํจ
builder = PizzaBuilder()
director = PizzaDirector(builder)
margherita = director.prepare_marinara()
margherita.pizza_state()
meat_lovers = director.prepare_meat_lovers()
meat_lovers.pizza_state()
vegetarian = director.prepare_vegetarian()
vegetarian.pizza_state()
๋ฐ์ํ
'๐บ๏ธ Design Pattern' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Design Pattern] Proxy Pattern - ํ๋ก์ ํจํด (0) | 2024.05.27 |
---|---|
[Design Pattern] Singleton Pattern - ์ฑ๊ธํค ํจํด & Metaclass (0) | 2024.05.21 |
[Design Pattern] Prototype Pattern - ํ๋กํ ํ์ ํจํด (0) | 2024.05.21 |
[Design Pattern] Abstract Factory Pattern - ์ถ์ ํฉํ ๋ฆฌ ํจํด (0) | 2024.04.08 |
[Design Pattern] Factory Method Pattern - ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด (0) | 2024.04.08 |