Abstract Factory là một pattern thiết kế cho phép tạo ra một nhóm các đối tượng liên quan mà không cần xác định trước lớp cụ thể của chúng.
Vấn đề
Ví dụ, chúng ta đang cần xây dựng một app mô phỏng của hàng nội thất. Code của chúng ta sẽ bao gồm các lớp đại diện cho:
1. Một nhóm các sản phẩm liên quan: Ghế, Sofa và Bàn
2. Một số biến thể của nhóm các sản phẩm này. Ví dụ cả 3 sản phẩm Ghế, Sofa và Bàn có các loại phong cách: Cổ điển, Hiện đại và Nghệ thuật
Đồng thời, chúng ta sẽ không muốn thay đổi code hiện tại khi thêm các sản phẩm mới hay các phong cách mới.
Giải pháp
Theo pattern thiết kế Abstract Factory, chúng ta sẽ cần định nghĩa các interface cho mỗi sản phẩm Bàn, Ghế, Sofa. Sau đó, chúng ta có thể tạo các phong cách khác nhau của từng sản phẩm dựa trên các interface. Ví dụ: Ghế Hiện Đại, Ghế Cổ Điển và Ghế Nghệ thuật đều implement interface Ghế. Tất cả các loại bàn đều implement interface Bàn.
Bước tiếp theo là tạo interface Abstract Factory — một interface có danh sách các phương thức tạo cho tất cả các sản phẩm thuộc họ sản phẩm (ví dụ: createChair, createSofa và createCoffeeTable). Các phương thức này phải trả về các loại sản phẩm trừu tượng được biểu thị bằng các interface mà chúng ta đã trích xuất trước đó: Ghế, Sofa, CoffeeTable, v.v.
Đối với mỗi nhóm sản phẩm thuộc cùng 1 phong cách, chúng ta tạo ra các lớp Factory dựa trên Abstract Interface. Trong đó, Factory là một lớp trả về các sản phẩm thuộc một loại cụ thể. Ví dụ: ModernFurnitureFactory chỉ có thể tạo các đối tượng ModernChair, ModernSofa và ModernCoffeeTable.
Code của khách hàng phải hoạt động với cả factory và sản phẩm thông qua giao diện trừu tượng tương ứng của chúng. Điều này cho phép bạn thay đổi loại nhà máy mà bạn chuyển sang code của khách hàng, cũng như các biến thể của sản phẩm mà code của khách nhận được mà không thay đổi code của khách.
Cấu trúc
Ưu nhược điểm
Ưu điểm
- Bạn có thể chắc chắn rằng các sản phẩm bạn nhận được từ các Factory đều tương thích với nhau.
- Bạn tránh sự phụ thuộc chặt chẽ giữa các sản phẩm cụ thể và code của khách hàng.
- Nguyên tắc trách nhiệm duy nhất. Bạn có thể để code tạo sản phẩm vào một lớp duy nhất, giúp code dễ maintain hơn.
- Nguyên tắc đóng/mở. Bạn có thể thêm các biến thể mới của sản phẩm mà không cần thay đổi code của khách hàng hiện có.
Nhược điểm
- Code có thể trở nên phức tạp hơn mức cần thiết vì nhiều interface và lớp mới được tạo ra.
Original article: https://refactoring.guru/design-patterns/abstract-factory