Template Method: khung pha chế và Hollywood principle

Định nghĩa Template Method, khung pha trà cà phê với móc treo, và nguyên tắc đừng gọi chúng tôi chúng tôi sẽ gọi bạn.
Trung bìnhDesign pattern ~60 phút

Giới thiệu

Bài này học Template Method giữ khung chung cho nhiều món. Khung này giúp thêm món mới mà không sửa code cũ.

Kiến thức cần nhớ

Khung giữ cấu trúc

  • Template Method là khung thuật toán nằm ở lớp cha.
  • Lớp con chỉ điền bước riêng, không đổi thứ tự.
  • Ví dụ đời thường: khuôn làm bánh quyết định các bước chung.
  • Dùng khi nhiều quy trình giống nhau 80%.

Trà và cà phê bốn bước

  • Cả hai cùng trình tự: đun, pha, rót, thêm gia vị.
  • Đun và rót giống nhau nên viết sẵn ở lớp cha.
  • Pha và thêm gia vị khác nhau nên để lớp con viết.
  • Ví dụ đời thường: trà hãm lá, cà phê pha phin.
# Khung pha chế: cha giữ thứ tự, con điền bước
class DoUong:
    def pha_che(self):  # khung 4 bước cố định
        self.dun_nuoc()  # bước chung viết sẵn
        self.pha()       # bước riêng con tự viết
        self.rot()       # bước chung viết sẵn
        if self.muốn_gia_vi():  # móc treo hỏi ý
            self.them_gia_vi()

Móc treo và Hollywood

  • Móc treo là bước có sẵn đáp án mặc định.
  • Lớp con có thể ghi đè hoặc bỏ qua móc.
  • Hollywood: con ngồi chờ, khung gọi đúng lúc.
  • Ví dụ đời thường: khách kiêng đường thì bỏ qua bước đường.
Khía cạnhBước trừu tượngMóc treo
Lớp conBắt buộc viếtTùy chọn ghi đè
Khung có sẵnKhông cóCó đáp án mặc định
Dùng khiBước nào cũng khácHiếm khi ngoại lệ

Ví dụ

  • Input: pha trà chanh -> Output: 4 bước chạy đủ, gia vị là chanh.
  • Câu này cho thấy bước chung và riêng phối hợp.
  • Input: pha cà phê kiêng đường -> Output: bỏ bước đường, 3 bước còn lại chạy.
  • Câu này cho thấy móc treo giúp bỏ qua linh hoạt.

💻 Bài tập

Ngôn ngữ: C++17 (hoặc Java). Nộp vào day-034/. Mỗi bước ghi vào std::vector<std::string> log để test thứ tự.

Bài 1: Trà và cà phê

class CaffeineBeverage {
 public:
  void prepareRecipe();                 // final: đun, pha, rót, (móc) thêm gia vị
  const std::vector<std::string> &log() const;
  virtual ~CaffeineBeverage() = default;
 protected:
  virtual void brew() = 0;
  virtual void addCondiments() = 0;
  virtual bool customerWantsCondiments() { return true; }   // hook
 private:
  void boilWater(); void pourInCup();
};
Lớpbrew()addCondiments()
Tea"ngâm trà""thêm chanh"
Coffee"lọc cà phê""thêm đường và sữa"

CoffeeWithHook nhận bool wantSugar qua constructor và ghi đè hook.

Tea            -> [đun nước, ngâm trà, rót ra cốc, thêm chanh]
Coffee         -> [đun nước, lọc cà phê, rót ra cốc, thêm đường và sữa]
CoffeeWithHook(false) -> [đun nước, lọc cà phê, rót ra cốc]

Ràng buộc: prepareRecipe không virtual (hoặc final trong Java). Lớp con không đổi được thứ tự.

Bài 2: Khung xử lý file dữ liệu

Viết DataImporter::run(path) với các bước cố định: open → parseLine cho từng dòng → validate → save → report. Hook bool skipHeader() mặc định true.

Viết CsvImporter (tách bằng dấu phẩy) và TsvImporter (tách bằng tab). Dòng không hợp lệ bị bỏ qua và đếm lại.

users.csv có 1 header + 4 dòng, 1 dòng thiếu cột -> report: "3 hợp lệ, 1 lỗi"

Bài 3: Hollywood trong sắp xếp (nâng cao)

std::sort là một Template Method: khung sắp xếp cố định, bạn chỉ cung cấp phép so sánh.

  1. Tự viết template<class T> void mySort(std::vector<T>&, bool (*less)(const T&, const T&)) (insertion sort). Dùng cho struct Duck { std::string name; int weight; } sắp theo cân nặng.
  2. Viết 3 câu trong README.md: điểm giống và khác giữa cách này và Template Method dùng kế thừa.
  3. So sánh Template Method với Strategy: bảng 3 dòng (cơ chế, lúc nào đổi được hành vi, ai giữ khung).

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

  • Test thứ tự log Bài 1 pass cho cả 3 lớp.
  • Bài 2: thêm JsonLinesImporter chỉ cần 1 file mới.
  • Bài 3 có bảng so sánh với Strategy.
  • Giải thích được nguyên lý Hollywood bằng một ví dụ trong code của mình.

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

  • Template Method giữ cái gì và nhả cái gì?
  • Hai bước nào của trà và cà phê giống nhau?
  • Móc treo khác bước trừu tượng thế nào?
  • Hollywood principle nghĩa là ai gọi ai?

🌕 Bạn đã hoàn thành ngày 34. 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.