תבנית Observer
חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 73 מתוך 91.
תבנית Observer היא תבנית עיצוב התנהגותית שיוצרת קשר של אחד לרבים בין אובייקטים. כאשר אובייקט אחד (הנושא) משנה את מצבו, כל התלויים בו (המשקיפים) מקבלים הודעה ומתעדכנים באופן אוטומטי.
חשבו על הרשמה לניוזלטר. הניוזלטר הוא הנושא, והמנויים הם צופים. כשמתפרסמת מהדורה חדשה, כל המנויים מקבלים אותה באופן אוטומטי, בלי שהניוזלטר יצטרך לדעת את הפרטים של כל מנוי.
הנה מימוש בסיסי ב-PHP:
<?php
interface Observer {
public function update(string $message): void;
}
class Newsletter {
private array $subscribers = [];
public function subscribe(Observer $observer): void {
$this->subscribers[] = $observer;
}
public function publish(string $content): void {
foreach ($this->subscribers as $subscriber) {
$subscriber->update($content);
}
}
}
class EmailSubscriber implements Observer {
public function __construct(private string $email) {}
public function update(string $message): void {
echo "Sending to {$this->email}: $message\n";
}
}
$newsletter = new Newsletter();
$newsletter->subscribe(new EmailSubscriber("alice@example.com"));
$newsletter->subscribe(new EmailSubscriber("bob@example.com"));
$newsletter->publish("New article released!");
פלט:
Sending to alice@example.com: New article released!
Sending to bob@example.com: New article released!התבנית מנתקת את הנושא מהצופים בו. המחלקה Newsletter לא צריכה לדעת אם היא מודיעה למנויים בדוא״ל, למנויי SMS או לשירותי הודעות דחיפה. היא פשוט קוראת ל־update() בכל רכיב שמממש את הממשק Observer. כך אפשר להוסיף סוגים חדשים של צופים בקלות, בלי לשנות את הקוד הקיים.
אתגר
קלבואו נבנה מערכת התראות על מחירי מניות באמצעות דפוס Observer. כאשר מחיר של מניה משתנה, יש להודיע אוטומטית לכל המשקיעים הרשומים: זהו יישום מושלם של הדפוס בעולם האמיתי.
תארגן את הקוד שלך בארבעה קבצים:
Observer.php: הגדר ממשקObserverעם מתודה אחת,update(string $stockName, float $price): void. זהו החוזה שעל כל הצופים לקיים כדי לקבל התראות.Investors.php: כלול את קובץ Observer וצור שתי מחלקות שמממשות את הממשק:EmailInvestor: מקבלת כתובת אימייל בבנאי שלה (השתמש בקידום פרמטרים בבנאי). המתודהupdate()שלה מדפיסה"Email to [email]: [stockName] is now $[price]"SmsInvestor: מקבלת מספר טלפון בבנאי שלה. המתודהupdate()שלה מדפיסה"SMS to [phone]: [stockName] is now $[price]"
Stock.php: כלול את קובץ Observer וצור מחלקהStockשפועלת כנושא. המניה שלך צריכה:- לשמור את שם המניה ואת המחיר הנוכחי (השתמש בקידום פרמטרים בבנאי עבור השם, ואתחל את המחיר ל-
0.0) - לנהל מערך פרטי של צופים
- לכלול מתודה
subscribe(Observer $observer): voidלהוספת צופים - לכלול מתודה
setPrice(float $price): voidשמעדכנת את המחיר ומודיעה לכל הצופים
update()של כל צופה עם שם המניה והמחיר החדש.- לשמור את שם המניה ואת המחיר הנוכחי (השתמש בקידום פרמטרים בבנאי עבור השם, ואתחל את המחיר ל-
main.php: כלול את הקבצים Investors ו-Stock. תקבל שלוש קלטים: שם מניה, כתובת אימייל ומספר טלפון.צור
Stockעם השם שהתקבל. רשוםEmailInvestorעם כתובת האימייל ו-SmsInvestorעם מספר הטלפון.הגדר את מחיר המניה ל-
150.50כדי להפעיל התראות לכל המנויים.
דפוס Observer שומר על מחלקת Stock מנותקת משיטות ההתראה הספציפיות. אפשר להוסיף בקלות PushInvestor או SlackInvestor בהמשך, בלי לשנות כלל את מחלקת Stock.
נסו בעצמכם
<?php
require_once 'Investors.php';
require_once 'Stock.php';
// קראו את הקלטים
$stockName = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));
// TODO: צרו Stock עם השם הנתון
// TODO: רשמו EmailInvestor כמנוי באמצעות כתובת האימייל
// TODO: רשמו SmsInvestor כמנוי באמצעות מספר הטלפון
// TODO: הגדירו את מחיר המניה ל-150.50 כדי להפעיל התראות
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח $thisמתודותמאפייניםבנאי (__construct)הורס (__destruct)חזרה: מחשבון פשוט4ירושה
ירושה בסיסיתמילת המפתח parent::דריסת מתודותמילת המפתח finalמחלקות מופשטותסיכום – היררכיית עובדים7כימוס
ציבורי, מוגן, פרטימפרטי גישה לעומקמתודות גישה ועדכוןהסתרת מידעקידום פרמטרים בבנאי (8.0)סיכום – מערכת רישומי תלמידים2מרחבי שמות וטעינה אוטומטית
מבוא למרחבי שמותמילת המפתח useתקן הטעינה האוטומטית PSR-4הטוען האוטומטי של Composerסיכום – פרויקט מאורגן5ממשקים וחוזים
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםממשק לעומת מחלקה מופשטתרמזי טיפוסים עם ממשקיםסיכום - מחשבון צורות8מתודות קסם
מבוא למתודות קסם__toString ו־__debugInfo__get, __set, __isset, __unset__call ו־__callStatic__clone ושיבוט אובייקטים__serialize ו־__unserializeסיכום – אוסף מותאם אישית3מאפייני מחלקה
מאפייני מופע לעומת מאפיינים סטטייםקבועים במחלקותמתודות ומאפיינים סטטייםמאפיינים פרטיים ומוגניםמאפיינים לקריאה בלבד (PHP 8.1)סיכום – מנהל חשבון בנק6פולימורפיזם
בחינה מחדש של דריסת מתודותפולימורפיזם באמצעות ממשקיםרמזי טיפוסים וטיפוסי איחודקישור סטטי מאוחרסיכום — מעבד תשלומיםתרגלו בעצמכם: קומפיילר PHP אונליין