תבנית שיטת התבנית
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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 שבמתודת התבנית. היא מונעת מתת־מחלקות לשנות את מבנה האלגוריתם. התבנית אידיאלית כשיש לכם כמה מחלקות שפועלות לפי אותו תהליך עבודה, אך נבדלות בפרטי המימוש. הוספת סוג מסמך חדש פירושה יצירת תת־מחלקה חדשה בלי לגעת בקוד קיים.
אתגר
קלבואו נבנה מערכת ליצירת דוחות באמצעות דפוס שיטת התבנית. סוגים שונים של דוחות פועלים לפי אותו מבנה: יחידה של כותרת, יחידה של נתונים ויחידה של סיכום, אבל כל סוג דוח מעצב את היחידות האלה באופן שונה. שיטת התבנית תגדיר את תהליך העבודה, בעוד שמחלקות הבת יוכלו להתאים אישית כל שלב.
תחלקו את הקוד שלכם בין ארבעה קבצים:
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() והדפיסו את הדוח המלא
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח $thisמתודותמאפייניםבנאי (__construct)הורס (__destruct)חזרה: מחשבון פשוט4ירושה
ירושה בסיסיתמילת המפתח parent::דריסת מתודותמילת המפתח finalמחלקות מופשטותסיכום – היררכיית עובדים7כימוס
ציבורי, מוגן, פרטימפרטי גישה לעומקמתודות גישה ועדכוןהסתרת מידעקידום פרמטרים בבנאי (8.0)סיכום – מערכת רישומי תלמידים10מושגי OOP מתקדמים
הרכבה לעומת ירושההזרקת תלויותמחלקות אנונימיותטיפוסי Enum (PHP 8.1)סיבים (PHP 8.1)העמקה בשכפול אובייקטיםמחוללים ואיטרטורים13תבניות עיצוב חלק 2
תבנית הפקודהתבנית המתאםתבנית העיצובןתבנית שיטת התבניתתבנית המצבתבנית המורכבתבנית המאגר2מרחבי שמות וטעינה אוטומטית
מבוא למרחבי שמותמילת המפתח useתקן הטעינה האוטומטית PSR-4הטוען האוטומטי של Composerסיכום – פרויקט מאורגן5ממשקים וחוזים
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםממשק לעומת מחלקה מופשטתרמזי טיפוסים עם ממשקיםסיכום - מחשבון צורות8מתודות קסם
מבוא למתודות קסם__toString ו־__debugInfo__get, __set, __isset, __unset__call ו־__callStatic__clone ושיבוט אובייקטים__serialize ו־__unserializeסיכום – אוסף מותאם אישית3מאפייני מחלקה
מאפייני מופע לעומת מאפיינים סטטייםקבועים במחלקותמתודות ומאפיינים סטטייםמאפיינים פרטיים ומוגניםמאפיינים לקריאה בלבד (PHP 8.1)סיכום – מנהל חשבון בנק6פולימורפיזם
בחינה מחדש של דריסת מתודותפולימורפיזם באמצעות ממשקיםרמזי טיפוסים וטיפוסי איחודקישור סטטי מאוחרסיכום — מעבד תשלומיםתרגלו בעצמכם: קומפיילר PHP אונליין