Menu
Coddy logo textTech

תבנית שיטת התבנית

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Python של Coddy. שיעור 52 מתוך 64.

תבנית שיטת התבנית מגדירה את השלד של אלגוריתם במחלקת בסיס, ומאפשרת למחלקות משנה לדרוס שלבים מסוימים בלי לשנות את מבנה האלגוריתם.

הנה מחלקת בסיס עם מתודת תבנית:

class DataProcessor:
    def process(self):
        """מתודת תבנית המגדירה את מבנה האלגוריתם"""
        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...")

מתודת התבנית process() מגדירה את שלבי האלגוריתם, בעוד שהמימוש של process_data() נשאר למחלקות המשנה.

צרו מחלקות קונקרטיות שמממשות את המתודה המופשטת:

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

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

כל מחלקה קונקרטית מספקת מימוש משלה לשלב הנדרש.

השתמשו בשיטת התבנית:

csv_processor = CSVProcessor()
csv_processor.process()

print()  # שורה ריקה

json_processor = JSONProcessor()
json_processor.process()

צרו דוגמה נוספת עם תבנית של משחק:

class Game:
    def play(self):
        """מתודת תבנית למשחק"""
        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()

פלט:

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

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

נקודה מרכזית: תבנית שיטת התבנית מגדירה מבנה אלגוריתם משותף במחלקת האב, ובה בעת מאפשרת למחלקות הבנות להתאים אישית שלבים מסוימים. מחלקת האב שולטת בזרימה הכללית, אך המחלקות הבנות מספקות את המימושים הספציפיים. כך מובטח מבנה עקבי, תוך מתן גמישות בשלבים הבודדים.

challenge icon

אתגר

בינוני

ממשו את תבנית Template Method בקובץ template.py. המחלקה המופשטת Report מכילה את שיטת התבנית generate(), שמריצה תמיד את אותם שלושה שלבים באותו סדר: header(), body(), footer().

  • header() משותפת לכל הדוחות ומדפיסה === Report ===.
  • body() היא מופשטת: כל מחלקת משנה מדפיסה תוכן משלה.
  • footer() היא נקודת הרחבה עם ברירת מחדל, === End ===, שמחלקת משנה יכולה לדרוס.

לאחר מכן כתבו את שני הדוחות הקונקרטיים:

  • SalesReport(total) שומרת את הסכום ב-self._total ומדפיסה בגוף הדוח Total sales: {total}.
  • InventoryReport(items) שומרת את הרשימה ב-self._items, מדפיסה Item: {item} עבור כל פריט בגוף הדוח, ודורסת את כותרת הסיום כדי להדפיס === {count} items ===.

הקובץ driver.py נעול: הוא יוצר דוחות וקורא להם ל-generate(). רק השלבים משתנים בין מחלקות המשנה; סדר השלבים מוגדר פעם אחת במחלקת הבסיס.

נסו בעצמכם

from template import SalesReport, InventoryReport

# מטפל במקרי בדיקה (אין לשנות)
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 iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Python אונליין