Mẫu thiết kế Factory Method hoặc Factory Pattern được sử dụng để xác định một interface hoặc lớp trừu tượng (abstract) để tạo một đối tượng nhưng để cho các lớp con quyết định lớp nào sẽ khởi tạo. Nói cách khác, các lớp con chịu trách nhiệm tạo ra thể hiện của lớp.
Phương thức Factory Method cũng được gọi là Virtual Constructor.
Nội dung chính
Lợi thế của Factory Design Pattern
- Mẫu thiế kế Factory Method cho phép các lớp con chọn kiểu đối tượng cần tạo.
- Nó thúc đẩy sự liên kết lỏng lẻo bằng cách loại bỏ sự cần thiết phải ràng buộc các lớp cụ thể vào code. Điều đó có nghĩa là code chỉ tương tác với interface hoặc lớp abstract, để nó sẽ làm việc với bất kỳ lớp nào implements interface đó hoặc extends lớp abstract.
Cách sử dụng mẫu thiết kế Factory Method
- Khi một lớp không biết những lớp con nào sẽ được yêu cầu để tạo ra.
- Khi một lớp muốn các lớp con của nó chỉ định các đối tượng được tạo ra.
- Khi các lớp cha chọn việc tạo các đối tượng cho các lớp con của nó.
Biểu đồ UML cho mẫu thiết kế Factory Method
- Chúng ta sẽ tạo ra một lớp trừu tượng Plan và các lớp cụ thể được extends lớp trừu tượng Plan. Tiếp theo định nghĩa một lớp nhà máy có tên GetPlanFactory.
- Lớp GenerateBill sẽ sử dụng GetPlanFactory để lấy đối tượng Plan. Nó sẽ chuyển thông tin (DOMESTICPLAN / COMMERCIALPLAN / INSTITUTIONALPLAN) tới GetPalnFactory để có được loại đối tượng cần thiết.
Ví dụ mẫu thiết kế Factory Method - tính hóa đơn điện
Step 1: Tạo lớp trừu tượng Plan.
package vn.viettuts.designpattern; public abstract class Plan { protected double rate; abstract void getRate(); public void calculateBill(int units) { System.out.println(units * rate); } }
Step 2: Tạo các lớp cụ thể extends lớp trừu tượng Plan.
package vn.viettuts.designpattern; public class DomesticPlan extends Plan { @Override public void getRate() { rate = 3.50; } }
package vn.viettuts.designpattern; public class CommercialPlan extends Plan { @Override public void getRate() { rate = 7.50; } }
package vn.viettuts.designpattern; public class InstitutionalPlan extends Plan { @Override public void getRate() { rate = 5.50; } }
package vn.viettuts.designpattern; public class GetPlanFactory { // sung dung phuong thuc getPlan de lay doi tuong co kieu Plan public Plan getPlan(String planType) { if (planType == null) { return null; } if (planType.equalsIgnoreCase("DOMESTICPLAN")) { return new DomesticPlan(); } else if (planType.equalsIgnoreCase("COMMERCIALPLAN")) { return new CommercialPlan(); } else if (planType.equalsIgnoreCase("INSTITUTIONALPLAN")) { return new InstitutionalPlan(); } return null; } }
Step 4: Sinh ra hóa đơn bằng cách sử dụng GetPlanFactory để lấy đối tượng của lớp cụ thể bằng cách truyền thông tin như sau DOMESTICPLAN hoặc COMMERCIALPLAN hoặc INSTITUTIONALPLAN.
package vn.viettuts.designpattern; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class GenerateBill { public static void main(String args[]) throws IOException { GetPlanFactory planFactory = new GetPlanFactory(); System.out.print("Nhap ten cua plan de tao hoa don: "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String planName = br.readLine(); System.out.print("Nhap so luong don vi cho hoa don: "); int unit = Integer.parseInt(br.readLine()); Plan p = planFactory.getPlan(planName); System.out.print("Hoa don " + planName + " cua " + unit + " don vi la: "); p.getRate(); p.calculateBill(unit); } }
Kết quả:
Nhap ten cua plan de tao hoa don: DOMESTICPLAN Nhap so luong don vi cho hoa don: 20 Hoa don DOMESTICPLAN cua 20 don vi la: 70.0