소프트웨어에 대한 모든 것

[ 디자인패턴][Builder] 빌더 패턴 본문

시스템 설계 및 디자인/디자인 패턴

[ 디자인패턴][Builder] 빌더 패턴

앤테바 2022. 3. 25. 14:43
반응형

빌더 패턴 정의

  • 복잡한 객체 생성을 표현으로부터 분리
  • 매개 변수가 많거나 선택적 매개변수를 써야할 상황이 많을 경우 이를 해결할 방법으로 주로 쓰이는 생성 패턴 방식

빌더 패턴을 이용하면:

  • 불필요한 생성자를 만들지 않고 객체를 생성합니다.
  • 데이터의 순서에 상관없이 객체를 생성합니다.
  • 사용자가 봤을 때 객체의 생성을 명시적으로 이해할 수 있습니다.

빌더 패턴 필요성

여기 링크에 빌더 패턴이 왜 필요한지 설명이 잘 되어 있습니다.

 

Problem 발생

https://refactoring.guru/design-patterns/builder

House 객체를 생성하는 방법에 대해서 고민해봅시다. 위의 그림 처럼 단순한 집도 있고, 차고지가 있는 집, 예쁜 조각상이 있는 집, 풀장이 있는 집, 수목이 화려한 집 등등등.. 아주 많은 조건을 가진 집들이 있을 것입니다.

 

이런 모든 조건들으 고려한 House 객체를 위해서 가장 간단한 솔루션은 기본 House 클래스를 확장하고 매개 변수의 모든 조합을 포함하는 하위 클래스 집합을 만드는 것입니다.

https://refactoring.guru/design-patterns/builder

위와 같은 해결책(디자인)은 많은 파라미터의 대부분을 사용하지 않을 것입니다. 그리고 생성자 호출을 굉장히 더럽게 만들 것입니다. 

 

Solution

빌더 패턴은 자체 클래스에서 객체 생성 코드를 추출하여 빌더라고 하는 별도의 객체로 이동토록 제안합니다

https://refactoring.guru/design-patterns/builder

빌더에서는 객체 생성에서 일련의 단계를 실행합니다. 동일한 빌드 단계 세트를 구현하지만 다른 방식으로 여러 다른 빌더 클래스를 작성할 수 있습니다. 즉 다양한 종류의 객체를 생성할 수 있습니다.

빌더 패턴 클래스 다이어그램

Builder 패턴 Class Diagram

빌더 패턴 활용

House 클래스

class House:
    def __init__(self):
        self.wall = None
        self.roof = None
        self.door = None

    def __str__(self):
        return f'wall : {self.wall}, roof : {self.roof}, door : {self.door}'

Builder 클래스들

class HouseBuilder(ABC):
    @abstractmethod
    def build_wall(self): pass

    @abstractmethod
    def build_roof(self): pass

    @abstractmethod
    def build_door(self): pass

    @abstractmethod
    def get_house(self): pass


class WoodHouseBuilder(HouseBuilder):
    def __init__(self):
        self.house = House()

    def reset(self):
        self.house = House()

    def build_wall(self):
        self.house.wall = '통나무'

    def build_roof(self):
        self.house.roof = '대나무'

    def build_door(self):
        self.house.door = '2 doors'

    def get_house(self):
        return self.house


class BrickHouseBuilder(HouseBuilder):
    def __init__(self):
        self.house = House()

    def reset(self):
        self.house = House()

    def build_wall(self):
        self.house.wall = '벽돌'

    def build_roof(self):
        self.house.roof = '기와'

    def build_door(self):
        self.house.door = '4 doors'

    def get_house(self):
        return self.house

Director 클래스

class CivilEngineer:
    def __init__(self, builder):
        self.builder = builder

    def construct_house(self):
        self.builder.reset()
        self.builder.build_wall()
        self.builder.build_roof()
        self.builder.build_door()

    def get_house(self):
        return self.builder.get_house()

클라이언트 사용 코드

wood_house_builder = WoodHouseBuilder()
engineer = CivilEngineer(wood_house_builder)
engineer.construct_house()
house = engineer.get_house()
print(f'Builder constructed, {house}')

출력

Builder constructed, wall : 통나무, roof : 대나무, door : 2 doors

 

참고 자료

https://www.geeksforgeeks.org/builder-design-pattern/

https://refactoring.guru/design-patterns/builder

https://junhyunny.github.io/information/design-pattern/builder-pattern/

https://jdm.kr/blog/217

https://lee1535.tistory.com/104

 

 

반응형
Comments