-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuilder.cpp
More file actions
168 lines (136 loc) · 3.29 KB
/
builder.cpp
File metadata and controls
168 lines (136 loc) · 3.29 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
Builder pattern is different from other creational patterns (factory method, .etc). Builder does not require products have same interface functions.
Sometimes, user derived class to create different objects is a good way, but there might be many class.
Or you can use different parameter flags in constructor to control differ steps, this is not good.
You can defined a builder class that contains all steps to build different products.
Client code can select necessary steps to build their specific product.
It applied to below:
1. Difference products creation steps are similar, only have minor differ steps.
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// can define various products
class product
{
public:
void printParts() const
{
for (auto p : _parts)
{
cout << p << endl;
}
cout << "\n\n";
}
vector<string> _parts;
};
/*Builder interface specifies methods to create difference part of product.*/
class builder
{
public:
virtual ~builder() {}
virtual void createPartA() const = 0;
virtual void createPartB() const = 0;
virtual void createPartC() const = 0;
};
class concreteBuilder : public builder
{
public:
concreteBuilder()
{
}
~concreteBuilder()
{
//if (_prod) delete _prod;
}
void create()
{
_prod = new product();
}
void createPartA() const override
{
_prod->_parts.push_back("Part A");
}
void createPartB() const override
{
_prod->_parts.push_back("Part B");
}
void createPartC() const override
{
_prod->_parts.push_back("Part C");
}
product *getProduct()
{
return this->_prod;
}
private:
product *_prod;
};
/*
The class director is optional. It is responsible for calling the building steps according to specific order.
Client code can control builder directly, but if we have set up the fixed steps to build a specific product, then client code can call director easily.
And client code does not know the creation details.
*/
class director
{
public:
void setBuilder(builder *blder) { _blder = blder; }
void buildPartA()
{
_blder->createPartA();
}
void buildCompleteProduct()
{
_blder->createPartA();
_blder->createPartB();
_blder->createPartC();
}
private:
builder *_blder;
};
void clientAction(director &dirct)
{
concreteBuilder *builder1 = new concreteBuilder();
dirct.setBuilder(builder1);
builder1->create();
cout << "Build basic part of product, only build part A:" << endl;
dirct.buildPartA();
product *p = builder1->getProduct();
if (p)
{
p->printParts();
delete p;
p = nullptr;
}
builder1->create();
cout << "Build a complete product:" << endl;
dirct.buildCompleteProduct();
p = builder1->getProduct();
if (p)
{
p->printParts();
delete p;
p = nullptr;
}
// customerize to create product without using director class
cout << "Customer to build product:" << endl;
builder1->create();
builder1->createPartB();
builder1->createPartC();
p = builder1->getProduct();
if (p)
{
p->printParts();
delete p;
p = nullptr;
}
delete builder1;
};
int main()
{
director *dt = new director();
clientAction(*dt);
delete dt;
return 0;
}