VieTopik
Tiếng HànTiếng AnhIT
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
Kiến trúc và chất lượng codeDesign pattern
Bài 12/17
5 phút

Factory

Nội dung bài · 5 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt

Khách chọn cách giao trên trang đặt hàng, API nhận được một chuỗi như "express". Cần một chỗ đổi chuỗi đó thành object ExpressShipping. Nếu mỗi controller tự làm bằng if riêng, thêm cách giao mới lại phải sửa khắp nơi. Factory gom việc tạo object về một chỗ.

Khái niệm

🏭 Factory: class hoặc method chuyên tạo object, nhận một lựa chọn và trả về object phù hợp dưới kiểu interface.

Strategy trả lời "có những cách làm nào". Factory trả lời "với lựa chọn này thì dùng cách nào". Nơi gọi chỉ đưa lựa chọn, không phải biết class cụ thể.

Ví dụ

Dùng lại ShippingStrategy và ba class của bài Strategy:

// Main.java
void main() {
    String method = "express";   // khách gửi lên
    System.out.println(
        ShippingFactory.create(method).fee(200000));
    // 50000
}

// ShippingFactory.java
class ShippingFactory {
    public static ShippingStrategy create(
            String method) {
        switch (method) {
            case "standard":
                return new StandardShipping();
            case "express":
                return new ExpressShipping();
            case "pickup":
                return new PickupShipping();
            default:
                throw new IllegalArgumentException(
                    "Không có cách giao: " + method);
        }
    }
}
  • create là static, gọi thẳng qua tên class như bài static của khoá Java Core.
  • Kiểu trả về là interface, nơi gọi không cần biết ExpressShipping.
  • switch chỉ nằm ở đây. Thêm cách giao mới: thêm class và thêm một case.
  • Gặp chuỗi lạ thì ném IllegalArgumentException như bài Exception, không lặng lẽ dùng một cách giao mặc định.

Trong controller, chuỗi method khách gửi lên đi qua factory rồi vào Checkout:

var checkout = new Checkout(
    ShippingFactory.create(method));

Thử ngay

Khách gửi lên một cách giao không có trong danh sách. Thay thân main bằng:

try {
    ShippingFactory.create("bay");
} catch (IllegalArgumentException e) {
    System.out.println(e.getMessage());
}

Đoán trước khi chạy: in ra gì?

Xem kết quả
Không có cách giao: bay

default của switch bắt mọi chuỗi không khớp. Nhờ ném lỗi, API báo sai ngay thay vì tính phí cho một cách giao không tồn tại.

Lỗi hay gặp

Tự new class cụ thể rải rác trong controller. Mỗi controller tự chọn class theo chuỗi, nên thêm cách giao mới phải sửa từng nơi.

// SAI — controller tự chọn class cụ thể
ShippingStrategy shipping;
if (method.equals("express")) {
    shipping = new ExpressShipping();
} else {
    shipping = new StandardShipping();
}
// ĐÚNG — hỏi factory, không tự chọn class
ShippingStrategy shipping =
    ShippingFactory.create(method);

Tóm tắt

  • Factory gom việc tạo object về một chỗ, trả về interface.
  • Nơi gọi chỉ đưa lựa chọn, không gọi new class cụ thể.
  • Lựa chọn không hợp lệ thì ném exception rõ ràng.
  • Hay đi cùng Strategy: Strategy định nghĩa các cách làm, Factory chọn cách.

Tự kiểm tra

0/3 câu
Câu 1

Controller tính phí cho cách giao khách chọn qua ShippingFactory. Controller cần biết những kiểu nào?

Câu 2

Thêm cách giao "cod" với cặp Strategy và Factory. Cần sửa những đâu?

Câu 3

Khi chuỗi không khớp case nào, vì sao nên ném exception thay vì trả StandardShipping?

StrategyDecorator

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt