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 dùng chỉ đưa lựa chọn, không phải biết class cụ thể.

Ví dụ

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

IShippingStrategy shipping =
    ShippingFactory.Create("express");
Console.WriteLine(shipping.Fee(200000m));   // 50000

public static class ShippingFactory
{
    public static IShippingStrategy Create(
        string method)
    {
        switch (method)
        {
            case "standard":
                return new StandardShipping();
            case "express":
                return new ExpressShipping();
            case "pickup":
                return new PickupShipping();
            default:
                throw new ArgumentException(
                    "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á C# 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 ArgumentException 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:

try
{
    ShippingFactory.Create("bay");
}
catch (ArgumentException e)
{
    Console.WriteLine(e.Message);
}

Đ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

Gọi 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ể
IShippingStrategy shipping;
if (method == "express")
{
    shipping = new ExpressShipping();
}
else
{
    shipping = new StandardShipping();
}
// ĐÚNG — hỏi factory, không tự chọn class
IShippingStrategy shipping =
    ShippingFactory.Create(method);

Tóm tắt

  • Factory gom việc tạo object về một chỗ, trả về interface.
  • Nơi dùng 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