תבנית הפקודה
חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 75 מתוך 91.
תבנית הפקודה היא תבנית עיצוב התנהגותית שהופכת בקשה לאובייקט עצמאי המכיל את כל המידע על הבקשה. ההמרה הזו מאפשרת להעביר בקשות כארגומנטים של מתודות, לדחות את ביצוע הבקשה או להוסיף אותה לתור, ולתמוך בפעולות שניתן לבטל.
חשוב על מסעדה.
כשאתה מזמין אוכל, המלצר רושם את ההזמנה שלך על פתק (הפקודה), לוקח אותה למטבח, והשף מבצע אותה. המלצר לא צריך לדעת לבשל; הוא רק מעביר את הפקודה.
כך מנותק מבקש הפעולה ממבצע הפעולה.
הנה מימוש בסיסי:
<?php
interface Command {
public function execute(): string;
}class Light {
public function on(): string { return "Light is ON"; }
public function off(): string { return "Light is OFF"; }
}class LightOnCommand implements Command {
public function __construct(private Light $light) {}
public function execute(): string {
return $this->light->on();
}
}class LightOffCommand implements Command {
public function __construct(private Light $light) {}
public function execute(): string {
return $this->light->off();
}
}
היוזם מפעיל פקודות בלי לדעת מה הן עושות:
<?php
class RemoteControl {
public function press(Command $command): string {
return $command->execute();
}
}$light = new Light();
$remote = new RemoteControl();
echo $remote->press(new LightOnCommand($light)) . "\n";
echo $remote->press(new LightOffCommand($light));
פלט:
Light is ON
Light is OFFתבנית הפקודה מצטיינת כשצריך לתור פעולות, לממש פונקציונליות של ביטול או לתעד פעולות. כל פקודה עומדת בפני עצמה, כך שקל להוסיף פקודות חדשות בלי לשנות קוד קיים.
אתגר
קלבואו נבנה מערכת פקודות לעורך טקסט באמצעות תבנית הפקודה. עורכי טקסט צריכים לעיתים קרובות לתמוך בפעולות כמו כתיבת טקסט, מחיקת טקסט וביטול פעולות: כל פעולה הופכת לאובייקט פקודה עצמאי שאפשר לבצע באמצעות ממשק אחיד.
תארגנו את הקוד שלכם בארבעה קבצים:
Command.php: הגדירו ממשקCommandעם מתודה יחידהexecute(): string. כך מוגדר החוזה שעל כל פקודות העורך לקיים.TextEditor.php, צרו מחלקהTextEditorשמייצגת את המקבל — האובייקט שמבצע בפועל את העבודה. העורך שלכם צריך:- לשמור את תוכן הטקסט הנוכחי (התחילו במחרוזת ריקה)
- להכיל מתודה
write(string $text): stringשמוסיפה טקסט לתוכן ומחזירה"Written: [text]" - להכיל מתודה
clear(): stringשמרוקנת את התוכן ומחזירה"Content cleared" - להכיל מתודה
getContent(): stringשמחזירה את התוכן הנוכחי
Commands.php: כללו את הקבצים Command ו-TextEditor. צרו שתי מחלקות פקודה שמממשות את הממשקCommand:WriteCommand: מקבלתTextEditorומחרוזת טקסט בבנאי שלה. המתודהexecute()שלה קוראת למתודתwrite()של העורך ומחזירה את התוצאה.ClearCommand: מקבלתTextEditorבבנאי שלה. המתודהexecute()שלה קוראת למתודתclear()של העורך ומחזירה את התוצאה.
main.php: כללו את הקובץ Commands. תקבלו שתי קלטים: סוג פקודה ("write"או"clear") ומחרוזת טקסט (שמשמשת רק לפקודות כתיבה).צרו מופע של
TextEditor. בהתאם לסוג הפקודה, צרו את אובייקט הפקודה המתאים. לאחר מכן צרו פונקציית מפעיל או מנגנון פשוט שקורא ל-execute()בפקודה ומדפיס את התוצאה.בשורה חדשה, הדפיסו את התוכן הנוכחי של העורך בפורמט הזה:
Content: [content](אם התוכן ריק, הדפיסו רקContent:בלי שום דבר אחרי הרווח).
האתגר הזה מדגים כיצד תבנית הפקודה עוטפת כל פעולה כאובייקט. המפעיל לא צריך לדעת אם הוא מבצע פקודת כתיבה או פקודת ניקוי. הוא פשוט קורא ל-execute() ומניח לפקודה לטפל בפרטים.
נסו בעצמכם
<?php
require_once 'Commands.php';
// קראו את הקלט
$commandType = trim(fgets(STDIN)); // "write" או "clear"
$text = trim(fgets(STDIN)); // טקסט עבור הפקודה write
// TODO: צרו מופע של TextEditor
// TODO: בהתאם לסוג הפקודה, צרו את אובייקט הפקודה המתאים
// - אם "write", צרו WriteCommand עם העורך והטקסט
// - אם "clear", צרו ClearCommand עם העורך
// TODO: צרו מנגנון הפעלה שקורא ל־execute() על הפקודה
// ומדפיס את התוצאה
// TODO: הדפיסו את התוכן הנוכחי של העורך בפורמט: "Content: [content]"
// (אם הוא ריק, הדפיסו רק "Content: " בלי דבר אחרי הרווח)
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
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 אונליין