Builder Design Pattern
Builder Design Pattern
Vấn đề
- Class
Product
với nhiều thuộc tính và phương thức. - Việc khởi tạo đối tượng
Product
đòi hỏi nhiều bước và thứ tự cụ thể. Điều này tạo ra sự phức tạp khi viết code và khó khăn trong việc quản lý và bảo trì code. - Đây chính là vấn đề mà
Builder Design Pattern
có thể giải quyết.
Giải pháp
Builder Design Pattern
giúp tách rời quá trình xây dựng đối tượng khỏi đối tượng được tạo ra.- Điều này giúp giảm bớt sự phức tạp và tăng tính linh hoạt của code.
- Khi áp dụng pattern này, việc khởi tạo đối tượng
Product
trở nên dễ dàng hơn và code trở nên gọn gàng, dễ đọc hơn.
Một số ví dụ thực tế
Builder Design Pattern
thường được sử dụng trong các tình huống như :- Xây dựng các đối tượng phức tạp.
- Tạo ra các đối tượng có nhiều biến thể.
Khái niệm
Builder Design Pattern
gồm có 4 thành phần chính:- Product: Đối tượng cuối cùng mà ta muốn xây dựng.
- Builder: Interface định nghĩa các bước để xây dựng một đối tượng
Product
. - ConcreteBuilder: Implementation cụ thể của
Builder
, xây dựng và trả về đối tượngProduct
. - Director: Sử dụng
Builder
để xây dựng đối tượng Product.
Sơ đồ UML của
Builder Design Pattern
:classDiagram Director "1" --> "1" Builder : uses Builder <|-- ConcreteBuilder Builder "1" --> "1" Product : builds class Director{ +Construct(builder: Builder) } class Builder{ +BuildPartA() +BuildPartB() +GetResult() Product } class ConcreteBuilder{ +BuildPartA() +BuildPartB() +GetResult() Product } class Product{ +Add(part: string) +Show() }
Code
- Dưới đây là ví dụ về cách sử dụng
Builder Design Pattern
trong C++ và Golang.
C++:
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
// Product
class Product {
public:
void Add(string part) {
parts.push_back(part);
}
void Show() {
for (int i = 0; i < parts.size(); i++) {
cout << parts[i] << ", ";
}
}
private:
vector<string> parts;
};
// Builder
class Builder {
public:
virtual void BuildPartA() = 0;
virtual void BuildPartB() = 0;
virtual Product* GetResult() = 0;
};
// ConcreteBuilder
class ConcreteBuilder : public Builder {
public:
void BuildPartA() {
product->Add("PartA");
}
void BuildPartB() {
product->Add("PartB");
}
Product* GetResult() {
return product;
}
private:
Product* product = new Product();
};
// Director
class Director {
public:
void Construct(Builder* builder) {
builder->BuildPartA();
builder->BuildPartB();
}
};
// Client code
int main() {
Director* director = new Director();
Builder* builder = new ConcreteBuilder();
director->Construct(builder);
Product* product = builder->GetResult();
product->Show();
return 0;
}
Golang:
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
// Product
type Product struct {
parts []string
}
func (p *Product) Add(part string) {
p.parts = append(p.parts, part)
}
func (p *Product) Show() {
fmt.Println(strings.Join(p.parts, ", "))
}
// Builder
type Builder interface {
BuildPartA()
BuildPartB()
GetResult() *Product
}
// ConcreteBuilder
type ConcreteBuilder struct {
product *Product
}
func (b *ConcreteBuilder) BuildPartA() {
b.product.Add("PartA")
}
func (b *ConcreteBuilder) BuildPartB() {
b.product.Add("PartB")
}
func (b *ConcreteBuilder) GetResult() *Product {
return b.product
}
// Director
type Director struct{}
func (d *Director) Construct(builder Builder) {
builder.BuildPartA()
builder.BuildPartB()
}
// Client code
func main() {
director := &Director{}
builder := &ConcreteBuilder{product: &Product{}}
director.Construct(builder)
product := builder.GetResult()
product.Show()
}
Ưu nhược điểm
Ưu điểm
- Tách biệt quá trình xây dựng đối tượng khỏi đối tượng được tạo ra.
- Code dễ đọc, dễ hiểu và dễ bảo dưỡng.
- Tăng tính linh hoạt của code.
Nhược điểm
- Tạo ra nhiều class và đối tượng không cần thiết, làm tăng độ phức tạp của code.
So sánh với các design pattern khác
Factory Pattern
: Dùng khi việc tạo đối tượng đơn giản và không cần nhiều bước.Prototype Pattern
: Dùng khi việc tạo đối tượng đơn giản nhưng tốn nhiều tài nguyên.Singleton Pattern
: Dùng khi chỉ cần một và chỉ một đối tượng duy nhất trong toàn bộ chương trình.
This post is licensed under CC BY 4.0 by the author.