Factory Method: framework và creator song song product

Định nghĩa Factory Method, khung cửa hàng nhượng quyền, và cấu trúc creator song song product qua New York và Chicago.
Trung bìnhDesign pattern ~60 phút

Giới thiệu

Bài này học cách nhượng quyền pizza 2 miền. Bạn để chi nhánh tự quyết khâu tạo.

Kiến thức cần nhớ

Vấn đề nhượng quyền

  • Quy trình chung nhưng vị mỗi vùng khác nhau.
  • Phô mai New York vỏ mỏng, Chicago vỏ dày.
  • 1 xưởng trung tâm không cân 2 chiều loại và vùng.
  • Ví dụ đời thường: cùng phở mà Bắc Nam khác vị.

Hai hệ song song

  • Một bên là khung cửa hàng giữ quy trình chung.
  • Một bên là họ pizza từng vùng.
  • Khâu tạo để trống, chi nhánh tự điền.
  • Ví dụ đời thường: công thức chung, bếp vùng tự nấu.

Thêm vùng mới không sửa cũ

  • Thêm California chỉ thêm chi nhánh và pizza mới.
  • Khung cũ và 2 vùng cũ nguyên vẹn.
  • Mỗi chi nhánh gắn với cụm pizza của mình.
  • Ví dụ đời thường: mở chi nhánh mới không sửa trụ sở.
Tiêu chíXưởng đơnFactory Method
Ai quyết tạo1 xưởng giữaMỗi chi nhánh tự quyết
Thêm vùng mớiMở xưởng sửaThêm nhánh mới
Quy trình chungKhông cóCó ở khung

Ví dụ

  • Input: gọi phô mai ở New York và Chicago. Output: 2 chiếc khác vị đúng vùng.
  • Giải thích: cùng khung chạy nhưng khâu tạo khác nhau.

💻 Bài tập

Ngôn ngữ: C++17 (hoặc Java). Nộp vào day-025/.

Bài 1: Factory Method cho chuỗi pizza

class PizzaStore {
 public:
  std::unique_ptr<Pizza> orderPizza(const std::string &type);   // không virtual: quy trình chung
  virtual ~PizzaStore() = default;
 protected:
  virtual std::unique_ptr<Pizza> createPizza(const std::string &type) = 0;  // factory method
};
Chi nhánhcreatePizza("cheese") trảname()cut()
NYPizzaStoreNYStyleCheesePizza"NY phô mai vỏ mỏng"cắt chéo
ChicagoPizzaStoreChicagoStyleCheesePizza"Chicago phô mai vỏ dày"cắt ô vuông

Mỗi chi nhánh có 2 loại: "cheese" và "veggie". orderPizza gọi createPizza rồi prepare, bake, cut, box. Ghi các bước vào log để test.

NYPizzaStore.orderPizza("cheese")      -> "NY phô mai vỏ mỏng", log có "cắt chéo"
ChicagoPizzaStore.orderPizza("cheese") -> "Chicago phô mai vỏ dày", log có "cắt ô vuông"
orderPizza("unknown")                  -> ném invalid_argument

Bài 2: Thêm vùng California

Thêm CaliforniaPizzaStore với 2 loại pizza mới. Chứng minh bằng git diff --stat: không file cũ nào đổi.

Viết thêm 3 câu: vì sao orderPizza không nên virtual, và điều gì xảy ra nếu chi nhánh ghi đè nó.

Bài 3: Factory Method ngoài pizza (nâng cao)

Viết khung xuất báo cáo:

class ReportExporter {
 public:
  std::string exportReport(const std::vector<Row> &rows);  // header + từng dòng + footer
 protected:
  virtual std::unique_ptr<Formatter> createFormatter() = 0;
};

Viết CsvExporter, JsonExporter, MarkdownExporter. Mỗi exporter tạo Formatter riêng với header(), row(const Row&), footer().

rows = [{name: "An", score: 9}, {name: "Bình", score: 7}]
CsvExporter      -> "name,score\nAn,9\nBình,7\n"
MarkdownExporter -> "| name | score |\n| --- | --- |\n| An | 9 |\n| Bình | 7 |\n"
JsonExporter     -> "[{\"name\":\"An\",\"score\":9},{\"name\":\"Bình\",\"score\":7}]"

✅ Tiêu chí hoàn thành

  • Test mẫu pass.
  • PizzaStore và ReportExporter không biết lớp sản phẩm cụ thể nào.
  • Thêm California chỉ thêm file mới.
  • Vẽ sơ đồ 2 hệ song song Creator và Product.

❓ Câu hỏi ôn tập

  • Factory Method là gì, nói 1 câu?
  • Khung giữ gì, chi nhánh giữ gì?
  • Vì sao thêm vùng không sửa khung?
  • Khác xưởng đơn ở đâu?

🌕 Bạn đã hoàn thành ngày 25. Làm hết bài tập phía trên rồi sang ngày tiếp theo.

Bớt paste mù, hiểu sâu từng dòng mình viết.

180 Days Challenge. 180 ngày cai nghiện vibe code.