C++/개념정리

빌더 패턴

jeongchanhyo 2025. 3. 11. 19:38

빌더 패턴이란?

객체 생성 과정을 캡슐화하고, 복잡한 객체를 단계적으로 구성할 수 있게 해주는 디자인 패턴 중 하나다.

이 패턴은 주로 객체를 생성하는 데 여러 단계가 필요하거나, 동일한 생성 과정을 통해 다양한 표현을 만들어야 할 때 유용하다.

빌더 패턴의 주요 구성 요소

  • Product(제품) : 최종적으로 생성될 복잡한 객체
  • Builder(빌더) : 객체를 생성하기 위한 인터페이스 또는 추상 클래스. 단계별로 객체를 구성하는 메서드를 정의한다.
  • ConcreteBuilder(구체적인 빌더) : Builder 인터페이스를 구현하여 실제로 Product를 만드는 클래스.
  • Director(디렉터) : 빌더를 사용해 객체를 구성하는 과정을 관리하는 클래스(이건 선택).

예시

1. Product 클래스

#include <iostream>
#include <string>
#include <memory>

using namespace std;

// 1. Product 클래스
class Pizza 
{
public:
    void setDough(const string& dough) { dough_ = dough; }
    void setSauce(const string& sauce) { sauce_ = sauce; }
    void setTopping(const string& topping) { topping_ = topping; }

    void show() const 
    {
        cout << "Pizza with " << dough_ << " dough, " 
             << sauce_ << " sauce, and " << topping_ << " topping." << endl;
    }

private:
    string dough_;
    string sauce_;
    string topping_;
};

피자 클래스를 만들어주고 도우, 소스, 토핑등을 활용할 함수와 변수를 만들어주고 복사해서 안전하게 가져가주겠다..

2. Builder

// 2. Builder 인터페이스
class PizzaBuilder 
{
public:
    virtual ~PizzaBuilder() = default;
    virtual void buildDough() = 0;
    virtual void buildSauce() = 0;
    virtual void buildTopping() = 0;
    virtual unique_ptr<Pizza> getPizza() = 0;
};

여기서는 피자를 만드는 토핑을 얹고, 소스를 뿌리고, 도우를 만드는 함수들을 만들어주겠다.

3. ConcreteBuilder

// 3. ConcreteBuilder 클래스
class HawaiianPizzaBuilder : public PizzaBuilder 
{
public:
    HawaiianPizzaBuilder() 
    {
        pizza_ = make_unique<Pizza>();
    }

    void buildDough() override 
    {
        pizza_->setDough("thick");
    }

    void buildSauce() override 
    {
        pizza_->setSauce("tomato");
    }

    void buildTopping() override 
    {
        pizza_->setTopping("pineapple and ham");
    }

    unique_ptr<Pizza> getPizza() override 
    {
        return move(pizza_);
    }

private:
    unique_ptr<Pizza> pizza_;
};

자세한 내용은 여기서 실행

4.Director

// 4. Director 클래스
class Cook 
{
public:
    void makePizza(PizzaBuilder& builder) 
    {
        builder.buildDough();
        builder.buildSauce();
        builder.buildTopping();
    }
};

객체를 생성하는 순서 정리 클래스

Main

int main() 
{
    Cook cook;
    HawaiianPizzaBuilder hawaiianBuilder;

    cook.makePizza(hawaiianBuilder);
    unique_ptr<Pizza> pizza = hawaiianBuilder.getPizza();
    pizza->show();

    return 0;
}

실행결과

이런식으로 잘 나온다.

 

빌더패턴의 장점

  • 객체 생성 과정을 추상화하여 코드 가독성과 유연성을 높임.
  • 불변 객체를 만들 때 유용
  • 생성자에 매개변수가 많아지는 생성자 문제를 해결 
  • 다양한 표현 생성 가능

빌더패턴의 단점

  • 코드 복잡도 증가
  • 초기 설계 시간 및 비용
  • 메모리 사용량 증가

언제 사용하면 좋을까?

  • 객체 생성 과정이 복잡하고 단계별로 나눌 수 있을 때
  • 동일한 생성 과정을 통해 다양한 객체를 만들어야 할 때
  • 객체의 생성과 표현을 분리하고 싶을 때

 

'C++ > 개념정리' 카테고리의 다른 글

템플릿 메서드 패턴  (2) 2025.03.07
상태 패턴  (0) 2025.03.05
전략패턴  (0) 2025.02.26
[디버그 입문]  (1) 2025.02.11
개념정리[연산자(&*)]  (0) 2025.02.07