classDiagram class Car { -int seats -str engine -bool gps +__str__() } class CarBuilder { -Car car +set_seats(int): CarBuilder +set_engine(str): CarBuilder +set_gps(bool): CarBuilder +build(): Car } class Director { -CarBuilder builder +construct_sports_car(): Car +construct_suv(): Car } Car <-- CarBuilder CarBuilder <-- Director
Builder 디자인 패턴
Builder 디자인 패턴
Python에서의 Builder 패턴 설명 및 구현
Builder 패턴은 복잡한 객체 생성 과정을 단계별로 나누어 수행하고, 최종적으로 완성된 객체를 반환하는 디자인 패턴입니다. 일반적으로 생성할 객체가 많은 속성을 가지고 있으며, 생성 과정이 복잡할 때 사용됩니다. Python에서는 이 패턴을 통해 여러 옵션을 가지는 객체를 유연하고 일관되게 구성할 수 있습니다. 이번 글에서는 Builder 패턴을 사용하는 이유와 Python에서 이를 구현하는 방법을 설명하겠습니다.
Builder 패턴을 사용하는 이유
Builder 패턴을 사용하는 주된 이유는 다음과 같습니다:
복잡한 객체 생성의 단순화: 객체가 여러 속성을 가지고 있고, 각 속성의 값에 따라 객체 생성이 복잡해질 때 Builder 패턴을 사용하여 각 속성을 단계별로 설정할 수 있습니다.
유연한 객체 구성: 객체 생성 시 선택적인 속성이나 단계가 있을 때, Builder 패턴을 사용하면 특정 속성을 제외하거나, 필요에 따라 추가하는 등 유연하게 객체를 구성할 수 있습니다.
일관성 유지: 동일한 객체를 여러 곳에서 생성할 때, Builder 패턴을 사용하면 객체 생성의 순서와 구성 방식을 표준화하여 일관성을 유지할 수 있습니다.
확장성: 새로운 속성을 추가하거나 생성 과정을 변경하는 경우, Builder 클래스의 메서드를 추가하거나 수정하여 손쉽게 확장할 수 있습니다.
Builder 패턴의 구조
Builder 패턴은 다음과 같은 구성 요소를 포함합니다:
- Product: 생성될 객체입니다.
- Builder: 객체 생성을 위한 단계별 인터페이스 또는 추상 클래스입니다.
- ConcreteBuilder:
Builder
인터페이스를 구현하여 각 단계별 세부 사항을 설정하는 클래스입니다. - Director:
Builder
를 사용하여 객체를 단계별로 생성하는 역할을 담당합니다.
Python에서의 Builder 패턴 구현 예제
아래 예제에서는 Builder 패턴을 사용하여 자동차(Car
) 객체를 생성하는 방법을 보여줍니다. 자동차는 좌석 수, 엔진 유형, GPS 유무 등 여러 옵션을 가지고 있으며, 이를 Builder 패턴으로 쉽게 설정할 수 있습니다.
class Car:
def __init__(self):
self.seats = None
self.engine = None
self.gps = None
def __str__(self):
return f"Car(seats={self.seats}, engine={self.engine}, gps={self.gps})"
class CarBuilder:
def __init__(self):
self.car = Car()
def set_seats(self, number):
self.car.seats = number
return self # 메서드 체이닝을 위해 self 반환
def set_engine(self, engine_type):
self.car.engine = engine_type
return self
def set_gps(self, gps_enabled):
self.car.gps = gps_enabled
return self
def build(self):
return self.car
class Director:
def __init__(self, builder):
self.builder = builder
def construct_sports_car(self):
return (self.builder
2)
.set_seats("V8")
.set_engine(True)
.set_gps(
.build())
def construct_suv(self):
return (self.builder
5)
.set_seats("V6")
.set_engine(False)
.set_gps( .build())
이 코드는 Builder 패턴을 사용하여 Car
객체를 단계적으로 생성하는 방식입니다. Builder 패턴을 사용하면 복잡한 객체를 생성하는 과정을 단순화하고 일관성 있게 관리할 수 있습니다. 각 클래스가 어떤 역할을 수행하는지와 코드의 동작 원리를 단계별로 설명하겠습니다.
1. Car
클래스 (Product)
class Car:
def __init__(self):
self.seats = None
self.engine = None
self.gps = None
def __str__(self):
return f"Car(seats={self.seats}, engine={self.engine}, gps={self.gps})"
Car
클래스는 생성될 객체로, 자동차의 속성을 정의합니다.self.seats
,self.engine
,self.gps
속성은 각각 좌석 수, 엔진 종류, GPS 여부를 나타냅니다.__str__
메서드는Car
객체의 정보를 문자열로 반환하여, 객체를 쉽게 확인할 수 있게 해줍니다.
2. CarBuilder
클래스 (Builder)
class CarBuilder:
def __init__(self):
self.car = Car()
CarBuilder
클래스는Car
객체를 구성하는 빌더 역할을 합니다.self.car = Car()
로Car
객체를 초기화하여 빌더가 자동차 객체의 속성을 단계적으로 설정할 수 있게 합니다.
def set_seats(self, number):
self.car.seats = number
return self # 메서드 체이닝을 위해 self 반환
set_seats
메서드는Car
객체의seats
속성을 설정합니다.- 메서드가
self
를 반환함으로써 메서드 체이닝을 지원하여, 여러 설정을 순차적으로 호출할 수 있습니다.
def set_engine(self, engine_type):
self.car.engine = engine_type
return self
set_engine
메서드는Car
객체의engine
속성을 설정합니다.
def set_gps(self, gps_enabled):
self.car.gps = gps_enabled
return self
set_gps
메서드는Car
객체의gps
속성을 설정합니다.
def build(self):
return self.car
build
메서드는 최종적으로 완성된Car
객체를 반환합니다.CarBuilder
를 사용하여 설정한 속성들을 포함한Car
객체가 반환됩니다.
3. Director
클래스
class Director:
def __init__(self, builder):
self.builder = builder
Director
클래스는CarBuilder
인스턴스를 받아 특정 설정에 맞는Car
객체를 구성하는 역할을 합니다.
def construct_sports_car(self):
return (self.builder
2)
.set_seats("V8")
.set_engine(True)
.set_gps( .build())
construct_sports_car
메서드는 스포츠카를 구성합니다.set_seats(2)
,set_engine("V8")
,set_gps(True)
를 통해 2인승, V8 엔진, GPS가 있는 스포츠카를 생성합니다.- 마지막에
build()
를 호출하여 완성된Car
객체를 반환합니다.
def construct_suv(self):
return (self.builder
5)
.set_seats("V6")
.set_engine(False)
.set_gps( .build())
construct_suv
메서드는 SUV를 구성합니다.set_seats(5)
,set_engine("V6")
,set_gps(False)
를 통해 5인승, V6 엔진, GPS가 없는 SUV를 생성합니다.- 최종적으로
build()
를 호출하여 구성된Car
객체를 반환합니다.
사용 예제
= CarBuilder()
builder = Director(builder)
director
= director.construct_sports_car()
sports_car print(sports_car) # 출력: Car(seats=2, engine=V8, gps=True)
= director.construct_suv()
suv print(suv) # 출력: Car(seats=5, engine=V6, gps=False)
CarBuilder
인스턴스를 생성하여,Director
가 빌더를 사용하도록 합니다.construct_sports_car
및construct_suv
를 호출하여 각각의 설정에 맞는Car
객체를 생성하고 출력합니다.
Builder 패턴의 장점
- 유연성: 각 속성을 메서드 체이닝으로 설정할 수 있어 원하는 속성만 선택적으로 적용 가능
- 확장성: 추가 속성을 쉽게 추가할 수 있어 유지보수가 용이
- 재사용성: 동일한 빌더를 여러 객체에 재사용 가능
- 코드 가독성: 객체 생성 코드가 일관되어 가독성이 높아짐
Builder 패턴 다이어그램
다음은 Builder 패턴을 시각적으로 설명하는 UML 다이어그램입니다.
결론
Builder 패턴은 Python에서 복잡한 객체 생성 과정을 단순화하고 유연하게 만드는 데 유용한 패턴입니다. 특히 선택적이거나 설정 가능한 속성이 많은 객체를 생성할 때, 이 패턴을 통해 생성 과정을 단계별로 나누어 일관된 객체를 얻을 수 있습니다.