Thinking Different








Builder Pattern - 빌더 패턴


  • 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다.
  • 쉽게 말해서 하나의 객체를 생성할때 객체를 이루는 구성요소들을 분리하여 객체의 세부 구성요소 클래스들을 별도로 만들고 그 구성 요소 클래스들을 조합하여 하나의 객체를 만드는 것이다.
  • 자동차를 만든다고 한다면 자동차의 부품들을 모아서 하나의 자동차를 만드는 것을 예로 들 수 있다.





샘플 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//------------------------------------------------------------------
// Product 클래스
class Product
{
};
 
//------------------------------------------------------------------
// Builder 인터페이스
class Builder
{
public:
    virtual Product* getResult() = 0;
    virtual void buildPart() = 0;
};
 
//------------------------------------------------------------------
// ConcreteBuilder 상속 클래스
class ConcreteBuilder : public Builder
{
public:
    void buildPart() override { pProduct = new Product; }
    Product* getResult() { return pProduct; }
 
private:
    Product* pProduct;
};
 
//------------------------------------------------------------------
// Director 클래스
class Director
{
public:
    Director(Builder* builder) : pBuilder(builder) {}
    ~Director() { if (pBuilder) delete pBuilder; }
 
public:
    Product* construct()
    {
        pBuilder->buildPart();
        return pBuilder->getResult();
    }
 
private:
    Builder* pBuilder;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    Director* pDirector = new Director(new ConcreteBuilder());
    Product* pProduct = pDirector->construct();
 
    delete pProduct;
    delete pDirector;
 
    return 0;
}




예제를 통한 빌더 패턴(Builder Pattern) 알아보기



예제) 자동차 생성 예제


다음과 같이 자동차를 만드는 Car 클래스가 있고 Car 안에는 3가지의 부품(엔진, 바디, 휠)이 포함된다. 이 Car 클래스는 Builder 클래스에 의해서 생성이 되며, Builder 클래스는 제품군 별로 (Ford, Jeep) 2가지 빌더 하위 클래스를 선언하였다.

각 빌더에서는 Car 클래스에 생성되는 Part 군을 생성해서 돌려준다. Director 클래스에서는 construct 함수를 통해서 Car를 만들기만 하면 끝이 난다.



예제 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//------------------------------------------------------------------
// Car Part 클래스
class CEngine
{
public:
    CEngine(int mph) : mMPH(mph) {}
    int  GetMPH() const { return mMPH; }
 
private:
    int mMPH;    // 엔진 마력
};
 
class CWheel
{
public:
    CWheel(int size) : mSize(size) {}
    int GetSize() const { return mSize; }
 
private:
    int mSize;    // 휠 사이즈
};
 
class CBody
{
public:
    CBody(string shape) : mShape(shape) {}
    string GetShape() const { return mShape; }
 
private:
    string mShape;
};
 
//------------------------------------------------------------------
// Product 클래스
class Car
{
public:
    Car() : mEngine(NULL), mWheel(NULL), mBody(NULL) {}
    ~Car() { if (mEngine) delete mEngine; if (mWheel) delete mWheel; if (mBody) delete mBody; }
 
public:
    void SetEngine(CEngine* engine) { mEngine = engine; }
    void SetWheel(CWheel* wheel) { mWheel = wheel; }
    void SetBody(CBody* body) { mBody = body; }
    void SetManufacturer(string m) { mManufacturer = m; }
 
    void print() const
    {
        cout << "제조 회사 : " << mManufacturer << endl;
        cout << "엔진 마력 : " << mEngine->GetMPH() << endl;
        cout << "휠 사이즈 : " << mWheel->GetSize() << endl;
        cout << "외형 타입 : " << mBody->GetShape() << endl;
    }
 
private:
    CEngine* mEngine;
    CWheel* mWheel;
    CBody* mBody;
    string mManufacturer;
};
 
//------------------------------------------------------------------
// Builder 인터페이스
class Builder
{
public:
    virtual CEngine* GetEngine() = 0;
    virtual CWheel* GetWheel() = 0;
    virtual CBody* GetBody() = 0;
    virtual string GetManufacturer() = 0;
};
 
//------------------------------------------------------------------
// JeepBuilder 상속 클래스
class JeepBuilder : public Builder
{
public:
    CEngine* GetEngine() override { return new CEngine(120); }
    CWheel* GetWheel() override { return new CWheel(20); }
    CBody* GetBody() override { return new CBody("SUV"); }
    string GetManufacturer() override { return "Jeep"; }
};
 
//------------------------------------------------------------------
// FordBuilder 상속 클래스
class FordBuilder : public Builder
{
public:
    CEngine* GetEngine() override { return new CEngine(150); }
    CWheel* GetWheel() override { return new CWheel(18); }
    CBody* GetBody() override { return new CBody("해치백"); }
    string GetManufacturer() override { return "Ford"; }
};
 
//------------------------------------------------------------------
// Director 클래스
class Director
{
public:
    Director(Builder* builder) : pBuilder(builder) {}
    ~Director() { if (pBuilder) delete pBuilder; }
 
public:
    Car* construct()
    {
        Car* pCar = new Car;
 
        pCar->SetBody(pBuilder->GetBody());
        pCar->SetEngine(pBuilder->GetEngine());
        pCar->SetWheel(pBuilder->GetWheel());
        pCar->SetManufacturer(pBuilder->GetManufacturer());
 
        return pCar;
    }
 
private:
    Builder* pBuilder;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    Director* pDirector = new Director(new FordBuilder());
    Car* pCar = pDirector->construct();
    
    pCar->print();
 
    delete pCar;
    delete pDirector;
 
    return 0;
}


예제 결과)