Menu
Coddy logo textTech

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

חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 78 מתוך 91.

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

שקול לבנות סוגים שונים של מסמכים.

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

<?php
abstract class DocumentGenerator {
    // מתודת התבנית - מגדירה את מבנה האלגוריתם
    public final function generate(): string {
        $output = $this->createHeader();
        $output .= $this->createContent();
        $output .= $this->createFooter();
        return $output;
    }
    
    // שלבים שיש לממש במחלקות יורשות
    abstract protected function createHeader(): string;
    abstract protected function createContent(): string;
    abstract protected function createFooter(): string;
}

class HtmlDocument extends DocumentGenerator {
    protected function createHeader(): string {
        return "<html><head></head><body>";
    }
    
    protected function createContent(): string {
        return "<p>Hello World</p>";
    }
    
    protected function createFooter(): string {
        return "</body></html>";
    }
}

class TextDocument extends DocumentGenerator {
    protected function createHeader(): string {
        return "=== DOCUMENT ===\n";
    }
    
    protected function createContent(): string {
        return "Hello World\n";
    }
    
    protected function createFooter(): string {
        return "=== END ===";
    }
}

$html = new HtmlDocument();
echo $html->generate() . "\n";

$text = new TextDocument();
echo $text->generate();

פלט:

<html><head></head><body><p>Hello World</p></body></html>
=== DOCUMENT ===
Hello World
=== END ===

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

challenge icon

אתגר

קל

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

תחלקו את הקוד שלכם בין ארבעה קבצים:

  • ReportGenerator.php: צרו מחלקה מופשטת בשם ReportGenerator שמגדירה את השלד של אלגוריתם יצירת הדוחות. המחלקה שלכם צריכה:
    • לקבל כותרת לדוח בבנאי שלה (השתמשו בקידום מאפיינים בבנאי)
    • לכלול מתודה ציבורית final בשם generate(): string שקוראת לשלושה שלבים לפי הסדר: createTitle(), createBody() ו-createSummary(), ומשרשרת את התוצאות שלהם
    • להצהיר על שלוש מתודות מוגנות ומופשטות שעל מחלקות הבת לממש: createTitle(): string, createBody(): string ו-createSummary(): string
  • HtmlReport.php: כללו את הקובץ ReportGenerator וצרו מחלקה בשם HtmlReport שיורשת ממנו. הדוח הזה מעצב את הפלט כ-HTML:
    • createTitle() מחזירה "<h1>[title]</h1>"
    • createBody() מחזירה "<p>Report data goes here</p>"
    • createSummary() מחזירה "<footer>End of report</footer>"
  • PlainTextReport.php: כללו את הקובץ ReportGenerator וצרו מחלקה בשם PlainTextReport שיורשת ממנו. הדוח הזה משתמש בעיצוב טקסט פשוט:
    • createTitle() מחזירה "### [title] ###\n"
    • createBody() מחזירה "Report data goes here\n"
    • createSummary() מחזירה "--- End of report ---"
  • main.php: כללו את שני קובצי הדוחות. תקבלו שתי קלטים: סוג דוח ("html" או "text") וכותרת לדוח.

    על סמך סוג הדוח, צרו את מחולל הדוחות המתאים עם הכותרת הנתונה. קראו ל-generate() והדפיסו את הדוח המלא.

דפוס שיטת התבנית מבטיח שכל הדוחות יפעלו לפי אותו מבנה בן שלושת השלבים, ובו בזמן מאפשר לכל סוג דוח לעצב את היחידות שלו באופן ייחודי. מילת המפתח final ב-generate() מונעת ממחלקות הבת לשנות את סדר האלגוריתם. הן יכולות להתאים אישית רק שלבים בודדים.

נסו בעצמכם

<?php

require_once 'HtmlReport.php';
require_once 'PlainTextReport.php';

// קראו את הקלט
$reportType = trim(fgets(STDIN));
$reportTitle = trim(fgets(STDIN));

// TODO: בהתאם לסוג הדוח ("html" או "text"),
// צרו את מחולל הדוח המתאים עם הכותרת הנתונה

// TODO: קראו ל־generate() והדפיסו את הדוח המלא

?>
quiz iconבחנו את עצמכם

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

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

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