Factory Method Design Pattern
Factory Method Design Pattern
Bối cảnh sử dụng
- Hãy tưởng tượng bạn là một lập trình viên đang phát triển một ứng dụng đọc sách điện tử.
- Ứng dụng của bạn hỗ trợ nhiều định dạng sách khác nhau như PDF, ePub, Mobi… Mỗi khi người dùng mở một cuốn sách, ứng dụng cần tạo ra một đối tượng
Book
tương ứng với định dạng của cuốn sách đó. - Nếu chúng ta sử dụng phương pháp truyền thống để khởi tạo đối tượng
Book
cho mỗi định dạng sách, chúng ta sẽ phải sử dụng nhiều câu lệnhif-else
hoặcswitch-case
. Điều này làm cho mã nguồn trở nên phức tạp và khó bảo trì. - Đây chính là lúc mà
Factory Method Design Pattern
có thể giúp ích.
Khái niệm:
Factory Method Design Pattern
thuộc nhóm khái niệm tạo lập (Creational Pattern).- Mục đích của nó là cung cấp một giao diện để tạo ra các đối tượng trong một lớp cha, nhưng cho phép các lớp con thay đổi loại đối tượng sẽ được tạo.
classDiagram
direction LR
BookFactory <|-- PDFBookFactory
BookFactory <|-- EpubBookFactory
Book <|-- PDFBook
Book <|-- EpubBook
Book <.. BookFactory
class BookFactory {
<<interface>>
+createBook() *Book*
}
note for PDFBookFactory "Book* createBook(){ return new PDFBookFactory() }"
class PDFBookFactory {
+createBook() Book*
}
class EpubBookFactory {
+createBook() Book*
}
class Book {
<<abstract>>
+readBook() *
}
class PDFBook {
+readBook()
}
class EpubBook {
+readBook()
}
Cách hoạt động
Factory Method Design Pattern
hoạt động bằng cách định nghĩa một interface hoặc lớp trừu tượng để tạo đối tượng, nhưng để cho lớp con quyết định lớp nào để khởi tạo.- Mục đích của việc này là để tạo ra một lớp chung cho việc khởi tạo đối tượng, nhưng tại thời điểm runtime, chúng ta có thể xác định lớp cụ thể nào sẽ được tạo.
- Thay vào đó, nếu sử dụng
Factory Method Design Pattern
, chúng ta chỉ cần định nghĩa một interfaceBookFactory
có phương thứccreateBook()
. Mỗi lớp định dạng sách sẽ triển khai interface này và tạo ra đối tượngBook
tương ứng.
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
class Book {
public:
virtual void read() = 0;
};
class PDFBook : public Book {
public:
void read() override {
// Read a PDF book
}
};
class EpubBook : public Book {
public:
void read() override {
// Read an Epub book
}
};
class BookFactory {
public:
virtual Book* createBook() = 0;
};
class PDFBookFactory : public BookFactory {
public:
Book* createBook() override {
return new PDFBook();
}
};
class EpubBookFactory : public BookFactory {
public:
Book* createBook() override {
return new EpubBook();
}
};
- Ta có thể sử dụng như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int bookType = 1; // 1 cho PDFBook, 2 cho EpubBook
BookFactory* factory;
if (bookType == 1) {
factory = new PDFBookFactory();
} else if (bookType == 2) {
factory = new EpubBookFactory();
} else {
std::cout << "Loại sách không hợp lệ" << std::endl;
return 1;
}
// Dù chọn loại factory nào thì những bước sau đều giữ nguyên
Book* book = factory->createBook(); // Tạo sách
book->read(); // Đọc sách
So sánh với các pattern khác
Factory Method Design Pattern
khác vớiSingleton Pattern
ở chỗ nó không chỉ tạo ra một đối tượng duy nhất.- Nó cũng khác với
Prototype Pattern
vì nó không sao chép đối tượng đã tồn tại mà tạo ra một đối tượng mới.
Ưu nhược điểm
Ưu điểm
Factory Method Design Pattern
giúp giảm sự phụ thuộc giữa các module của mã nguồn, giúp mã nguồn dễ dàng mở rộng hơn.- Nó cũng giúp tạo ra các đối tượng một cách linh hoạt hơn và giảm bớt sự phức tạp khi khởi tạo đối tượng.
Nhược điểm
- Một nhược điểm của
Factory Method Design Pattern là
nó có thể tạo ra nhiều lớp con chỉ để triển khai phương thức tạo đối tượng, điều này có thể làm cho mã nguồn trở nên phức tạp hơn.
This post is licensed under CC BY 4.0 by the author.