Menu
Coddy logo textTech

תבנית Observer

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 92 מתוך 110.

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

התבנית כוללת שני תפקידים מרכזיים: נושא שמנהל רשימה של משקיפים ומודיע להם על שינויים, ומשקיפים שנרשמים ומגיבים לעדכונים:

abstract class Observer {
  void update(String message);
}

class NewsAgency {
  final List<Observer> _observers = [];
  String _latestNews = '';

  void subscribe(Observer observer) {
    _observers.add(observer);
  }

  void unsubscribe(Observer observer) {
    _observers.remove(observer);
  }

  void publishNews(String news) {
    _latestNews = news;
    for (var observer in _observers) {
      observer.update(_latestNews);
    }
  }
}

class NewsChannel implements Observer {
  final String name;
  NewsChannel(this.name);

  @override
  void update(String message) {
    print('$name received: $message');
  }
}

void main() {
  var agency = NewsAgency();
  var cnn = NewsChannel('CNN');
  var bbc = NewsChannel('BBC');

  agency.subscribe(cnn);
  agency.subscribe(bbc);

  agency.publishNews('Breaking news!');
  // CNN קיבל: חדשות מתפרצות!
  // BBC קיבל: חדשות מתפרצות!
}

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

challenge icon

אתגר

קל

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

תארגן את הקוד שלך בשני קבצים:

  • stock_system.dart: צור כאן את מערכת התצפית שלך:
    • מחלקה מופשטת Investor עם מתודה void onPriceChange(String stockName, double price)
    • מחלקה DayTrader שמממשת את Investor. יש לה שדה name, ומתודת onPriceChange שלה מדפיסה: [name] sees [stockName] at $[price] - Making quick trade!
    • מחלקה LongTermInvestor שמממשת את Investor. יש לה שדה name, ומתודת onPriceChange שלה מדפיסה: [name] notes [stockName] at $[price] - Holding steady.
    • מחלקה StockTicker (הנושא) עם:
      • שדה String stockName
      • רשימה פרטית לאחסון משקיעים שנרשמו
      • מתודת subscribe(Investor investor) להוספת משקיע
      • מתודת unsubscribe(Investor investor) להסרת משקיע
      • מתודת updatePrice(double newPrice) שמודיעה לכל המשקיעים שנרשמו על המחיר החדש
  • main.dart: ייבא את מערכת המניות שלך והדגם את תבנית Observer בפעולה:
    • צור StockTicker עבור מניה בשם DART
    • צור DayTrader בשם Alice ו-LongTermInvestor בשם Bob
    • רשום את שני המשקיעים לטיקר
    • עדכן את המחיר ל-150.50 (יש להודיע לשני המשקיעים)
    • הדפס שורה ריקה
    • בטל את הרישום של Alice מהטיקר
    • עדכן את המחיר ל-155.75 (כעת יש להודיע רק ל-Bob)

הדוגמה הזו ממחישה כיצד תבנית Observer יוצרת מערכת עם צימוד רופף — StockTicker לא צריך לדעת אם הוא מודיע לסוחרי יום או למשקיעים לטווח ארוך; הוא פשוט קורא ל-onPriceChange עבור כל מי שנרשם!

הפלט הצפוי:

Alice sees DART at $150.5 - Making quick trade!
Bob notes DART at $150.5 - Holding steady.

Bob notes DART at $155.75 - Holding steady.

נסו בעצמכם

import 'stock_system.dart';

void main() {
  // TODO: צרו StockTicker עבור מניה בשם 'DART'
  
  // TODO: צרו DayTrader בשם 'Alice'
  
  // TODO: צרו LongTermInvestor בשם 'Bob'
  
  // TODO: רשמו את שני המשקיעים לעדכונים מהטיקר
  
  // TODO: עדכנו את המחיר ל-150.50 (שני המשקיעים אמורים לקבל הודעה)
  
  // TODO: הדפיסו שורה ריקה
  
  // TODO: בטלו את המנוי של Alice לעדכונים מהטיקר
  
  // TODO: עדכנו את המחיר ל-155.75 (רק Bob אמור לקבל הודעה כעת)
}
quiz iconבחנו את עצמכם

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

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

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