Dev/DesignPattern

[DesignPattern] Builder Pattern

황빵 2023. 4. 25. 20:43

Builder Pattern (Creational Pattern)

생성할 프로덕트의 구성요소가 많을때, 생성하는 빌더 클래스를 분리하여, 생성자의 파라미터가 많아졌을때, 가독성을 높이기 위해 사용한다.

Builder Pattern의 작동방식

우선 Builder Partten을 사용하기 위해서는 다음과 같은 요소들이 필요하다.

  • Builder 인터페이스
  • Builder 구현 클래스
  • 생성될 프로덕트 인터페이스
  • 생성될 프로덕트 구현 클래스

Builder Pattern을 사용하기 위해서는 다음과 같은 과정을 거친다.

빌더 패턴은 생성될 프로덕트 객체를 생성하는 과정이 너무 복잡할때 사용하는 패턴이다.
생성하는 과정이 복잡하다 = 생성될 프로덕트의 구성요소가 많다. 라는 의미인데 
빌더패턴을 통해서, 생성될 프로덕트 객체의 아규먼트를 세팅과정을 분리한다.

예를들어, 생성될 프로덕트 객체의 아규먼트가 3개라면, 3개의 세터 메서드를 통해
아규먼트를 세팅하고, 마지막에 build 메서드를 통해 프로덕트 객체를 생성한다.

이렇게 하면, 생성될 프로덕트 객체의 아규먼트가 많아져도, 생성하는 과정이 복잡해지지 않는다.

추가적으로, 세터 메서드에서 리턴을 객체 자신으로 하여 , 메서드 Chaining을 통해 
세팅하는 과정을 더욱 간결하게 만들 수 있다.

빌더 클래스 역시 인터페이스와 구현 클래스로 나눌 수 있다.

Builder 인터페이스 를 상속 받는 컨크리트 Builder 클래스를 정의한다.
생성될 프로덕트 객체의 세터 메서드를 정의한다.
build 메서드를 정의한다.

사용방법은 다음과 같다.

1. 빌더클래스의 인스턴스를 생성한다. 
2. 빌더클래스의 세터 메서드를 통해 프로덕트 객체의 아규먼트를 세팅한다.
3. build 메서드를 통해 프로덕트 객체를 생성한다.

Builder Pattern의 구현-1

class Cat:
    def __init__(self, height, weight, color):
        self.height = height
        self.weight = weight
        self.color = color

class CatBuilder:
    def __init__(self):
        self.height = None
        self.weight = None
        self.color = None

    def setHeight(self, height):
        self.height = height
        return self

    def setWeight(self, weight):
        self.weight = weight
        return self

    def setColor(self, color):
        self.color = color
        return self

    def build(self):
        return Cat(self.height, self.weight, self.color)

cat = CatBuilder().setHeight(10).setWeight(20).setColor("black").build()
print(cat.height, cat.weight, cat.color)

Builder Pattern의 구현-2

import math

class Vector: #  product
    def __init__(self, dim,  x, y, z):
        self.x = x
        self.y = y
        self.z = z
        dim = -1
        weight = 0

    def normalize(self):
        self.weight = self.getMagnitude()

    def getMagnitude(self):
        return math.sqrt(self.x**2 + self.y**2 + self.z**2)

    def getState(self):
        return (self.x, self.y, self.z)

    def getDim(self):
        return self.dim

class VectorBuilder: # builder
    def __init__(self):
        self.x = None
        self.y = None
        self.z = None
        self.dim = None

    def setX(self, x):
        self.x = x
        return self

    def setY(self, y):
        self.y = y
        return self

    def setZ(self, z):
        self.z = z
        return self

    def setDim(self, dim):
        self.dim = dim
        return self

    def build(self):
        vector = Vector(self.dim, self.x, self.y, self.z)

        return vector

class VectorBuilder2D(VectorBuilder): # concrete builder
    def __init__(self):
        super().__init__()
        self.dim = 2
        self.z = 0

class VectorBuilder3D(VectorBuilder): # concrete builder
    def __init__(self):
        super().__init__()
        self.dim = 3 

vector2d = VectorBuilder2D().setX(10).setY(20).build()
print(vector2d.getState())
vector3d = VectorBuilder3D().setX(10).setY(20).setZ(30).build()
print(vector3d.getState())
728x90
반응형