Tóm tắt Nhà máy quy mô tốt.
Có một nguyên tắc cơ bản quy định rằng một lớp nên làm tốt một việc. Vấn đề của bạn ở đây là bạn đang cố gắng làm cho nhiều lớp làm nhiều việc.
Bạn không cần phải gắn bó với một nhà máy trừu tượng. Bạn có thể (và nên có) một số:
AbstractProductAFactory
định nghĩa giao diện để sản xuất ProductA. Việc triển khai cụ thể của bạn (Concrete ProducttAFactory1, Concrete ProducttAFactory2) sẽ mở rộng nó.
AbstractProductBFactory
định nghĩa giao diện để sản xuất ProductB. Việc triển khai cụ thể của bạn ( ConcreteProductBFactory1
, ConcreteProductBFactory2
) sẽ mở rộng nó.
Nếu sau đó bạn cần một ProductC, hãy tạo một cái mới AbstractProductCFactory
. Không cần phải thay đổi bất kỳ nhà máy khác của bạn theo cách này.
CẬP NHẬT
Lý tưởng nhất là ProductA nên đại diện cho một loại sản phẩm - nghĩa là tất cả các sản phẩm có chung giao diện mà bạn đang gọi ProductA. Trong các bình luận tôi đề nghị rằng đây là một cái gì đó giống như Pizza:
interface AbstractPizzaFactory {
public Pizza buildPizza(List<Topping> toppings);
}
class ThinCrustPizzaFactory implements AbstractPizzaFactory {
public Pizza buildPizza(List<Topping> toppings){
...
}
}
class DeepDishPizzaFactory implements AbstractPizzaFactory {
public Pizza buildPizza(List<Topping> toppings){
...
}
}
Và như thế. Việc thêm PanPizzaFactory sẽ không ảnh hưởng đến bất kỳ lớp nào khác - đó chỉ là một triển khai cụ thể mới của PizzaFactory. Nếu bạn có các sản phẩm không phải là pizza - ví dụ như bánh sandwich, đó là nơi bạn tạo ra một nhà máy trừu tượng khác (ví dụ AbstractSandwichFactory
:).
Vấn đề thực sự là, bạn sẽ không muốn có một nhà máy trừu tượng xây dựng hai loại sản phẩm rất khác nhau với hai phương pháp "xây dựng" khác nhau. Nhóm chúng một cách hợp lý như bạn có thể để chúng chia sẻ một giao diện, và sau đó tạo một nhà máy trừu tượng xác định cách các nhà máy cụ thể nên xây dựng các triển khai của giao diện đó.