Menu
CoddyTech

Mẫu phương thức khuôn mẫu

Thuộc phần Lập trình hướng đối tượng trong hành trình Python của Coddy. Bài học 52 trên 64.

Mẫu Template Method định nghĩa khung của một thuật toán trong lớp cơ sở, cho phép các lớp con ghi đè các bước cụ thể mà không thay đổi cấu trúc của thuật toán.

Đây là lớp cơ sở có phương thức khuôn mẫu:

class DataProcessor:
    def process(self):
        """Phương thức khuôn mẫu (template method) xác định cấu trúc thuật toán (algorithm)"""
        self.read_data()
        self.process_data()
        self.save_data()
    
    def read_data(self):
        print("Reading data...")
    
    def process_data(self):
        raise NotImplementedError("Subclasses must implement this")
    
    def save_data(self):
        print("Saving data...")

Phương thức mẫu process() xác định các bước của thuật toán, còn process_data() được dành cho các lớp con triển khai.

Tạo các lớp cụ thể triển khai phương thức trừu tượng:

class CSVProcessor(DataProcessor):
    def process_data(self):
        print("Processing CSV data")

class JSONProcessor(DataProcessor):
    def process_data(self):
        print("Processing JSON data")

Mỗi lớp cụ thể cung cấp cách triển khai riêng cho bước bắt buộc.

Sử dụng phương thức khuôn mẫu:

csv_processor = CSVProcessor()
csv_processor.process()

print()  # Dòng trống

json_processor = JSONProcessor()
json_processor.process()

Tạo thêm một ví dụ với mẫu trò chơi:

class Game:
    def play(self):
        """Phương thức mẫu để chơi trò chơi"""
        self.start_game()
        self.play_game()
        self.end_game()
    
    def start_game(self):
        print("Game started!")
    
    def play_game(self):
        raise NotImplementedError("Define the game rules")
    
    def end_game(self):
        print("Game ended!")

class Chess(Game):
    def play_game(self):
        print("Playing chess - thinking strategically...")

class Soccer(Game):
    def play_game(self):
        print("Playing soccer - running and kicking...")

chess = Chess()
chess.play()

Đầu ra:

Reading data...
Processing CSV data
Saving data...

Reading data...
Processing JSON data
Saving data...
Game started!
Playing chess - thinking strategically...
Game ended!

Điểm chính: Mẫu Template Method định nghĩa cấu trúc thuật toán chung trong lớp cha, đồng thời cho phép các lớp con tùy chỉnh những bước cụ thể. Lớp cha kiểm soát luồng tổng thể, còn các lớp con cung cấp phần triển khai cụ thể. Nhờ vậy, cấu trúc luôn nhất quán nhưng từng bước vẫn linh hoạt.

challenge icon

Thử thách

Trung bình

Triển khai mẫu Template Method trong template.py. Lớp trừu tượng Report sở hữu phương thức mẫu generate(), phương thức này luôn chạy cùng ba bước theo cùng một thứ tự: header(), body(), footer().

  • header() được dùng chung cho mọi báo cáo và in ra === Report ===.
  • body() là phương thức trừu tượng: mỗi lớp con in nội dung riêng.
  • footer() là một hook có giá trị mặc định, === End ===, mà lớp con có thể ghi đè.

Sau đó, viết hai báo cáo cụ thể:

  • SalesReport(total) lưu tổng số vào self._total và in Total sales: {total} trong phần thân.
  • InventoryReport(items) lưu danh sách vào self._items, in Item: {item} cho từng mục trong phần thân, và ghi đè phần chân trang để in === {count} items ===.

driver.py bị khóa: tệp này tạo các báo cáo và gọi generate() trên chúng. Chỉ các bước giữa những lớp con là khác nhau; thứ tự các bước chỉ được định nghĩa một lần trong lớp cơ sở.

Tự làm thử

from template import SalesReport, InventoryReport

# Bộ xử lý test case (không thay đổi)
test_case = input()

if test_case == "sales_test":
    SalesReport(1500).generate()
elif test_case == "inventory_test":
    InventoryReport(["Laptop", "Mouse"]).generate()
elif test_case == "both_test":
    for report in [SalesReport(200), InventoryReport(["Pen"])]:
        report.generate()
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Python online