Bạn có 1 chương trình “sản xuất” hàng loạt sản phẩm liên quan đến nhau. Sau đó, bạn muốn thêm một vài đoạn mã “sản xuất” thêm các sản phẩm khác trong cùng chương trình mà không thay đổi những sản phẩm trước. Liệu có phương án nào khả thi để thực hiện hay không? Câu trả lời là “Có!”. Giải pháp bạn đang tìm kiếm chính là Abstract Factory Pattern. Vậy, Abstract Factory Pattern là gì? Những thành phần của Abstract Factory Pattern ra sao?
Tìm hiểu về Abstract Factory Pattern
Abstract Factory Pattern là gì?
Abstract Factory Pattern là một trong những Creational Design Pattern – phương pháp tốt nhất để tạo ra những Object. Abstract Factory Pattern hoạt động như một Super-Factory để tạo ra những Factory khác. Ta cũng có thể nói: Abstract Factory Pattern là Factory của các Factory.
Trong Abstract Factory Pattern sẽ có 1 Interface chịu trách nhiệm trong việc tạo ra 1 Factory, Factory sẽ sản xuất ra những Object liên quan mà không cần chỉ định rõ ràng các class của chúng.
Nghe giải thích theo cách này, bạn thấy Abstract Factory Pattern trừu tượng lắm đúng không?
Giải thích một cách dễ hiểu hơn:
Abstract Factory Pattern tương tự một nhà máy lớn sản xuất xe hơi. Một chiếc xe hơi sẽ có rất nhiều bộ phận, từ bánh xe, tay lái, cửa xe, động cơ, các mặt kính,…
Các Factory trong Abstract Factory Pattern sẽ chịu trách nhiệm sản xuất ra các bộ phận này.
Trong thực tế sẽ còn liên quan đến các việc khác như vận hành, lắp ráp, tổ chức sản xuất,… rất phức tạo.
Trong bài viết, Tino Group sẽ giữ nguyên một số từ tiếng Anh như sau để đảm bảo sự đồng nhất:
- Class: lớp
- Subclass: lớp con
- Interface: giao diện
- Abstract: trừu tượng
- Factory: nhà máy
- Pattern: mẫu/ khuôn
- Method: phương pháp, cách thức
- Object: đối tượng/ sản phẩm
Lợi ích của Abstract Factory Pattern
- Abstract Factory Pattern là Factory của các Factory. Vì thế, chương trình của bạn có thể dễ dàng mở rộng để chứa thêm các Factory khác, các subclass khác mà không làm ảnh hưởng đến những Factory, class đang có.
- Bạn có thể dễ dàng xây dựng một encapsulate – hệ thống đóng gói, sử dụng được nhiều Factory khác nhau, từ đó bạn có thể tạo ra nhiều sản phẩm khác nhau.
- Khi sử dụng Factory Method lớn với quá nhiều xử lý như: if-else hay switch-case. Bạn có thể sử dụng Abstract Factory Pattern để dễ dàng quản lý chương trình hơn, nhờ vào việc tự phân loại và gom các subclass vào cùng 1 Factory của Abstract Factory Pattern.
Ngoài ra, Abstract Factory Pattern còn cung cấp:
- Nhiều hướng tiếp cận với Interface thay vì implement
- Ẩn đi sự phức tạp trong quá trình khởi tạo các Object đối với người dùng
- Hỗ trợ khởi tạo Object một cách độc lập với hệ thống thống sử dụng Object..
Những thành phần của Abstract Factory Pattern
Để có thể dễ dàng hiểu hơn về Abstract Factory Pattern, Tino Group sẽ đưa ra ví dụ về 1 cửa hàng sản xuất bàn ghế gỗ nhé! Chúng ta sẽ đặt vấn đề sau đó đưa ra giải pháp để giải quyết. Phần ví dụ này được dẫn lại theo Guru.
Vấn đề
Chúng ta đang sở hữu một cửa hàng đồ gỗ nội thất và chúng ta đang có các sản phẩm như sau: Chair + Sofa + CoffeeTable.
Với những sản phẩm đang bán này,chúng ta có thêm 3 phong cách của sản phẩm là: Modern, Victorian, ArtDeco.
Vấn đề chúng ta đang gặp phải là: làm cách nào để tạo ra các sản phẩm cùng 1 phong cách để tạo sự đồng nhất trong 1 căn phòng. Và hiện tại, khách hàng của chúng ta đang không vui vì sản phẩm họ nhận được là Chair phong cách Victorian quý tộc nhưng ghế Sofa lại là phong cách Modern hiện đại. Việc “râu ông này cắm cằm bà kia” sẽ mang lại sự khó chịu khi nhìn vào căn phòng.
Giải pháp
Vậy, giải pháp chúng ta cần đó chính là Abstract Factory Pattern. Việc chúng ta cần thực hiện đó chính là:
- Khai báo các Interface cho từng phong cách sản phẩm
- Dựa vào đó ta tiếp tục khai báo Interface sản phẩm cho từng phong cách để tạo ra sự đồng nhất như sau:
Như bạn có thể thấy, giờ đây các sản phẩm được phân loại theo từng nhóm phong cách riêng biệt. Mỗi phong cách, chúng ta sẽ tạo ra một AbstractFactory, trong mỗi Factory, chúng ta lại có các sản phẩm giống nhau ví dụ như:
ModernFurnitureFactory sẽ tạo ra các đối tượng(Object) sản phẩm tương ứng như: ModernChair, ModernSofa và ModernCoffeeTable.
Điều này sẽ giúp khách hàng của bạn mua được 1 loạt sản phẩm tương tự nhau và không vi phạm hay bị lệch sang các sản phẩm bên trong các Factory khác.
Cấu trúc
Chúng ta sẽ đưa ra một mô hình lớn hơn trong việc sản xuất và ta sẽ có một sơ đồ như sau:
Trong đó, chúng ta sẽ có:
- Abstract Products: khai bao các Interface tập hợp những sản phẩm có cùng phong cách.
- Concrete Products: triển khai các sản phẩm theo từng nhóm phong cách nhất định. Ví dụ: mỗi Chair/Sofa sẽ phải đi theo 1 phong cách là Victorian/Modern.
- Abstract Factory Interface: đây là Interface tập hợp các method để tạo ra các sản phẩm Abstract.
- Concrete Factories: thực hiện các method của Abstract Factory. Mỗi Factory sẽ chỉ tạo ra một biến thể sản phẩm tương ứng.
- Cuối cùng, chúng ta có Client, họ sẽ có thể làm việc với bất cứ một Abstract Factory hay một sản phẩm Abstract nào, miễn là họ làm việc thông qua các Interface.
Ưu điểm và nhược điểm của Abstract Factory Pattern
Sau khi bạn đã nắm được những thông tin về thành phần của Abstract Factory Pattern, chúng ta sẽ tiếp tục tìm hiểu các ưu điểm và nhược điểm của Abstract Factory Pattern nhé!
Ưu điểm của Abstract Factory Pattern
Ưu điểm hữu ích nhất của Abstract Factory Pattern chính là có thể giúp Client có thể biết chính xác loại nào cần tạo ra, Factory nào sẽ tạo ra sản phẩm nào.
- Ngay trong ví dụ cụ thể bên trên, chúng ta có thể thấy mỗi Factory sẽ có chính xác class Object được tạo ra theo phong cách nào. Điều này sẽ khiến cho Client dễ dàng xác nhận và làm việc qua các Abstract Interface mà không bị lẫn lộn.
- Dễ dàng quản lý Concrete Products hơn. Nếu như bạn muốn thay đổi toàn bộ phong cách Object bên trong, bạn chỉ cần thay đổi cấu trúc của Concrete. Ví dụ từ Modern, bạn có thể thay đổi sang phong cách ArtDeco mà không cần thay đổi từng sản phẩm bên trong.
Nhược điểm của Abstract Factory Pattern
Nhược điểm lớn nhất và buộc phải xảy ra nếu bạn muốn thêm một sản phẩm mới đó chính là sự phức tạp trong cấu trúc Factory.
Muốn thêm 1 sản phẩm mới, bạn sẽ phải thay đổi các class bên trong Abstract Factory và tất cả các subclass của sản phẩm đó nếu có.
Đến đây, Tino Group đã giải thích về Abstract Factory Pattern cùng ví dụ theo cách dễ hiểu nhất. Có vẻ việc triển khai Abstract Factory Pattern thực sự phức tạp. Tuy nhiên, khi thiết kế mỗi bộ phận đảm nhận một công việc chuyên môn riêng sẽ giúp tổng thể đạt được mức độ hoàn chỉnh cao hơn. Tino Group hi vọng rằng, bạn sẽ có thể lựa chọn Pattern phù hợp và áp dụng thành công cho dự án của mình!
Bài viết có tham khảo từ: Stack Java, JavaTPoint, geeksforgeeks, TopDev, TutorialsPoint, Guru, GPCoder…
Những câu hỏi thường gặp về Abstract Factory Pattern
Nên sử dụng Factory Method hay Abstract Factory?
Sẽ không có một câu trả lời chính xác 100% cho câu hỏi này. Câu trả lời sẽ phụ thuộc vào việc bạn đang muốn xây dựng phần mềm/ ứng dụng của mình ra sao để chọn lựa Factory Method hay Abstract Factory; hoặc bạn sẽ cần phải linh hoạt áp dụng cả Factory Method hay Abstract Factory vào dự án của mình.
Khi nào nên sử dụng Factory Method?
Thông thường, Factory Method sẽ được sử dụng trong việc thay thế các toolkit hoặc framework nào đó. Đoạn mã framework đó cần phải tạo ra 1 đối tượng là những lớp con Abstract tương ứng, mục đích nhằm để tăng tính mềm dẻo của framework.
Ưu điểm của Factory Method ra sao?
Factory Method giúp hạn chế sự phụ thuộc giữa creator và concrete products.
Factory Method hỗ trợ gom các đoạn code tạo ra product tập trung lại với nhau để bạn có thể dễ dàng thao tác, theo dõi.
Việc mở rộng phần mềm sẽ đơn giản hơn, bạn chỉ cần thêm những đoạn code mới vào chương trình mà không cần phải gây đổ vỡ các cấu trúc ban đầu.
Khi nào nên sử dụng Factory Method?
Nên sử dụng Factory Method khi bạn muốn:
- Tạo ra cách mới trong việc khởi tạo Object
- Giảm bớt sự phụ thuộc
- Ẩn việc xử lý logic trong khi khởi tạo