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
.set_seats(2)
.set_engine("V8")
.set_gps(True)
.build())
def construct_suv(self):
return (self.builder
.set_seats(5)
.set_engine("V6")
.set_gps(False)
.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 selfset_engine메서드는Car객체의engine속성을 설정합니다.
def set_gps(self, gps_enabled):
self.car.gps = gps_enabled
return selfset_gps메서드는Car객체의gps속성을 설정합니다.
def build(self):
return self.carbuild메서드는 최종적으로 완성된Car객체를 반환합니다.CarBuilder를 사용하여 설정한 속성들을 포함한Car객체가 반환됩니다.
3. Director 클래스
class Director:
def __init__(self, builder):
self.builder = builderDirector클래스는CarBuilder인스턴스를 받아 특정 설정에 맞는Car객체를 구성하는 역할을 합니다.
def construct_sports_car(self):
return (self.builder
.set_seats(2)
.set_engine("V8")
.set_gps(True)
.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
.set_seats(5)
.set_engine("V6")
.set_gps(False)
.build())construct_suv메서드는 SUV를 구성합니다.set_seats(5),set_engine("V6"),set_gps(False)를 통해 5인승, V6 엔진, GPS가 없는 SUV를 생성합니다.- 최종적으로
build()를 호출하여 구성된Car객체를 반환합니다.
사용 예제
builder = CarBuilder()
director = Director(builder)
sports_car = director.construct_sports_car()
print(sports_car) # 출력: Car(seats=2, engine=V8, gps=True)
suv = director.construct_suv()
print(suv) # 출력: Car(seats=5, engine=V6, gps=False)CarBuilder인스턴스를 생성하여,Director가 빌더를 사용하도록 합니다.construct_sports_car및construct_suv를 호출하여 각각의 설정에 맞는Car객체를 생성하고 출력합니다.
Builder 패턴의 장점
- 유연성: 각 속성을 메서드 체이닝으로 설정할 수 있어 원하는 속성만 선택적으로 적용 가능
- 확장성: 추가 속성을 쉽게 추가할 수 있어 유지보수가 용이
- 재사용성: 동일한 빌더를 여러 객체에 재사용 가능
- 코드 가독성: 객체 생성 코드가 일관되어 가독성이 높아짐
Builder 패턴 다이어그램
다음은 Builder 패턴을 시각적으로 설명하는 UML 다이어그램입니다.
결론
Builder 패턴은 Python에서 복잡한 객체 생성 과정을 단순화하고 유연하게 만드는 데 유용한 패턴입니다. 특히 선택적이거나 설정 가능한 속성이 많은 객체를 생성할 때, 이 패턴을 통해 생성 과정을 단계별로 나누어 일관된 객체를 얻을 수 있습니다.
카테고리 다른 글
| Date | Title | Author |
|---|---|---|
| Nov 25, 2024 | Python 전략 패턴 | |
| Nov 25, 2024 | Python 옵저버 패턴 | |
| Nov 23, 2024 | Python 데코레이터 패턴 | |
| Nov 11, 2024 | 싱글톤 디자인 패턴 | |
| Sep 25, 2024 | 디자인패턴 선택 기준 | |
| Sep 25, 2024 | 자주사용되는 디자인패턴 1 | |
| Sep 25, 2024 | 자주사용되는 디자인패턴 2 |