Lớp học Creator
của bạn là nhà máy. Hãy gọi nó là ProductFactory
, để làm cho ví dụ rõ ràng hơn.
(tôi đang giả sử bạn đang sử dụng C++)
class Book : public Product
{
};
class Computer : public Product
{
};
class ProductFactory
{
public:
virtual Product* Make(int type)
{
switch (type)
{
case 0:
return new Book();
case 1:
return new Computer();
[...]
}
}
}
Gọi nó như thế này:
ProductFactory factory = ....;
Product* p1 = factory.Make(0); // p1 is a Book*
Product* p2 = factory.Make(1); // p2 is a Computer*
// remember to delete p1 and p2
Vì vậy, để trả lời câu hỏi của bạn:
gì nó phải làm gì với các lớp con? Và tôi phải sử dụng các lớp con nào cho các lớp học ?
Định nghĩa cho mẫu nhà máy là nhà sản xuất định nghĩa API chung để tạo các phiên bản của một loại nhất định (thường là giao diện hoặc lớp trừu tượng), nhưng loại thực thi được trả lại (do đó lớp con tham khảo) là trách nhiệm của nhà máy. Trong ví dụ này, nhà máy trả về Product
trường hợp, trong đó Book
và Computer
là các lớp con hợp lệ.
Có thành ngữ khác cho nhà máy, giống như có một API cho các nhà máy và việc triển khai cụ thể của nhà máy không chấp nhận một type
như trong ví dụ của tôi, nhưng họ đang kết hợp với các loại hình trường trở về, như thế này :
class ProductFactory
{
public:
virtual Product* Make() = 0;
}
class BookProductFactory : public ProductFactory
{
public:
virtual Product* Make()
{
return new Book();
}
}
Trong lớp này BookProductFactory
luôn trả về Book
trường hợp.
ProductFactory* factory = new BookProductFactory();
Product* p1 = factory->Make(); // p1 is a Book
delete p1;
delete factory;
Để làm cho nó rõ ràng, vì dường như có một chút nhầm lẫn giữa Abstract Factory
và Factory method
các mẫu thiết kế, chúng ta hãy xem một ví dụ cụ thể:
Sử dụng Abstract Factory
class ProductFactory {
protected:
virtual Product* MakeBook() = 0;
virtual Product* MakeComputer() = 0;
}
class Store {
public:
Gift* MakeGift(ProductFactory* factory) {
Product* p1 = factory->MakeBook();
Product* p2 = factory->MakeComputer();
return new Gift(p1, p2);
}
}
class StoreProductFactory : public ProductFactory {
protected:
virtual Product* MakeBook() { return new Book(); }
virtual Product* MakeComputer() { return new Computer(); }
}
class FreeBooksStoreProductFactory : public StoreProductFactory {
protected:
virtual Product* MakeBook() {
Book* b = new FreeBook(); // a FreeBook is a Book with price 0
return b;
}
}
Được sử dụng như sau:
Store store;
ProductFactory* factory = new FreeBooksStoreProductFactory();
Gift* gift = factory->MakeGift(factory);
// gift has a FreeBook (Book with price 0) and a Computer
delete gift;
delete factory;
Sử dụng phương pháp Factory
class Store {
public:
Gift* MakeGift() {
Product* p1 = MakeBook();
Product* p2 = MakeComputer();
return new Gift(p1, p2);
}
protected:
virtual Product* MakeBook() {
return new Book();
}
virtual Product* MakeComputer() {
return new Computer();
}
}
class FreeBooksStore : public Store {
protected:
virtual Product* MakeBook() {
Book* b = new FreeBook(); // a FreeBook is a Book with price 0
return b;
}
}
Đó được sử dụng như thế này:
Store* store = new FreeBooksStore();
Gift* gift = store->MakeGift();
// gift has a FreeBook (Book with price 0) and a Computer
delete gift;
delete store;
Khi bạn sử dụng một phân biệt type
như tôi đã làm trong ví dụ ban đầu, chúng tôi đang sử dụng parametized factory methods
- một phương pháp biết cách tạo các loại đối tượng khác nhau. Nhưng điều đó có thể xuất hiện ở dạng mẫu Abstract Factory
hoặc Factory Method
. Một mẹo ngắn gọn: nếu bạn đang mở rộng lớp nhà máy bạn đang sử dụng Abstract Factory. Nếu bạn mở rộng lớp bằng các phương thức tạo, thì bạn đang sử dụng các Phương thức của Nhà máy.
vì vậy, trong mã của bạn, ProductFactory là một Nhà máy Tóm tắt, và thực hiện là Phương pháp Nhà máy, phải không? – Alcott
Sự khác biệt giữa 'Abstract Factory' và' Factory Method' sẽ là câu hỏi riêng của nó :) Tóm lại, khi bạn sử dụng phân biệt kiểu như tôi đã làm trong ví dụ, chúng tôi đang sử dụng "phương pháp nhà máy được tối ưu hóa" - một phương pháp biết cách tạo các loại đối tượng khác nhau. Nhưng điều đó có thể xuất hiện trong mô hình Abstract Factory hoặc Factory Method. Một mẹo ngắn gọn: nếu bạn đang mở rộng lớp nhà máy bạn đang sử dụng 'Nhà máy trừu tượng'. Nếu bạn mở rộng lớp với phương thức _factory_, thì bạn đang sử dụng 'Method Methods'. Nếu sự khác biệt vẫn chưa rõ ràng đặt ra một câu hỏi khác trên SO. –
Để làm rõ. Câu trả lời của tôi không sử dụng mẫu thiết kế 'Factory method' nhưng mẫu thiết kế' Abstract Factory'. –