Facade: rạp hát tại gia và Least Knowledge

Định nghĩa Facade, quy trình xem phim mười bước gom thành một nút, và nguyên lý chỉ nói chuyện với bạn thân.
Trung bìnhDesign pattern ~60 phút

Giới thiệu

Bài này học Facade gom hệ phức tạp thành nút bấm đơn giản. Mặt tiền này giúp dùng rạp hát tại gia dễ dàng.

Kiến thức cần nhớ

Facade là gì

  • Facade là lớp mặt tiền đơn giản trước hệ con phức tạp.
  • Người dùng gọi mặt tiền thay vì gọi từng thiết bị.
  • Ví dụ đời thường: điều khiển tivi có một nút xem phim.
  • Dùng khi nhiều bước phải chạy đúng thứ tự.

Rạp hát hai nút bấm

  • Xem phim phải bật 6 thiết bị theo đúng thứ tự.
  • Nút xemPhim() chạy đủ 10 bước nhỏ tự động.
  • Nút ketThuc() tắt ngược lại cho an toàn.
  • Ví dụ đời thường: bấm một nút là đèn tắt, phim chạy.
# Mặt tiền gom nhiều bước thành 1 nút
class HomeTheater:
    def xem_phim(self):
        self.bap_nuoc()  # bước 1: bật máy bắp
        self.ha_den()    # bước 2: hạ đèn
        self.bat_may_chieu()  # bước 3: bật máy chiếu
        self.bat_phim()  # bước 4: chạy phim

Least Knowledge nói với bạn thân

  • Chỉ gọi đối tượng mình giữ trực tiếp.
  • Không gọi dây chuyền kiểu a.b.c.bat().
  • Ví dụ đời thường: nhờ lễ tân, không tự vào kho.
  • Chuỗi gọi dài làm đổi một chỗ vỡ cả chuỗi.
Khía cạnhAdapterFacade
Mục đíchDịch 1 giao diệnGom cả hệ con
Giao diện cũẨn điVẫn mở cho ai cần
Số bướcThường 1 bướcNhiều bước đúng thứ tự

Ví dụ

  • Input: bấm xemPhim() khi mọi máy đang tắt -> Output: phim chạy, đèn hạ, máy chiếu bật.
  • Câu này chứng minh mười bước gom thành một nút.
  • Input: bấm ketThuc() sau khi xem -> Output: mọi máy tắt theo thứ tự ngược.
  • Câu này chứng minh tắt máy cũng an toàn và gọn.

💻 Bài tập

Ngôn ngữ: C++17 (hoặc Java). Nộp vào day-031/. Mỗi thiết bị ghi hành động vào một std::vector<std::string> &log chung để test thứ tự.

Bài 1: Home Theater Facade

Thiết bịHàm
Amplifieron(), off(), setStreamingPlayer(StreamingPlayer&), setSurroundSound(), setVolume(int)
StreamingPlayeron(), off(), play(movie), stop()
Projectoron(), off(), wideScreenMode()
Screendown(), up()
TheaterLightson(), dim(int percent)
PopcornPopperon(), off(), pop()
class HomeTheaterFacade {
 public:
  HomeTheaterFacade(Amplifier&, StreamingPlayer&, Projector&, Screen&, TheaterLights&, PopcornPopper&);
  void watchMovie(const std::string &movie);  // đủ các bước theo đúng thứ tự log bên dưới
  void endMovie();                            // tắt ngược lại
};
watchMovie("Dune") -> log:
popper.on, popper.pop, lights.dim(10), screen.down, projector.on,
projector.wideScreenMode, amp.on, amp.setStreamingPlayer, amp.setSurroundSound, amp.setVolume(5),
player.on, player.play(Dune)
endMovie() -> popper.off, lights.on, screen.up, projector.off, amp.off, player.stop, player.off

Ràng buộc: gọi watchMovie 2 lần liên tiếp không bật lại thiết bị đang bật (Facade nhớ trạng thái).

Bài 2: Sửa vi phạm Least Knowledge

Code sau vi phạm nguyên lý:

double Station::temperature() { return thermometer.getSensor().getReading().celsius(); }
std::string Order::customerCity() { return customer.getAddress().getCity().getName(); }

Viết lại để mỗi hàm chỉ gọi "bạn thân". Viết 2 câu cho mỗi hàm: nếu lớp Reading đổi thì bản cũ vỡ ở đâu, bản mới vỡ ở đâu.

Bài 3: Facade cho thư viện phức tạp (nâng cao)

Giả lập hệ đặt vé với 4 lớp: SeatService, PaymentGateway, EmailService, LoyaltyService. Đặt vé cần: giữ ghế, thanh toán, cộng điểm, gửi email.

Viết BookingFacade::book(userId, showId, seatCount):

  • Thanh toán lỗi: nhả ghế đã giữ, không cộng điểm, không gửi email.
  • Gửi email lỗi: vé vẫn hợp lệ, ghi cảnh báo.
  • Trả BookingResult { bool ok; std::string reason; }.

Viết 3 test cho 3 kịch bản: thành công, thanh toán lỗi, email lỗi.

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

  • Test thứ tự log của Bài 1 pass.
  • Client vẫn gọi thẳng được từng thiết bị nếu cần (Facade không khóa hệ con).
  • Bài 3 có 3 test, thanh toán lỗi thì ghế được nhả.
  • Phân biệt được Facade, Adapter, Decorator bằng một câu mỗi pattern.

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

  • Facade là gì và mặt tiền giúp gì?
  • Nút xem phim gom những bước nào?
  • Least Knowledge cấm kiểu gọi nào?
  • Khi nào không nên dùng Facade?

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