Menu
Coddy logo textTech

תבנית הצופה (אירועים)

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C# של Coddy. שיעור 54 מתוך 70.

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

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

public class Stock
{
    private decimal _price;
    
    public event Action<decimal> PriceChanged;
    
    public decimal Price
    {
        get => _price;
        set
        {
            _price = value;
            PriceChanged?.Invoke(_price);  // הודע לכל הצופים
        }
    }
}

public class PriceAlert
{
    public void OnPriceChanged(decimal newPrice)
    {
        Console.WriteLine($"Alert: Price is now {newPrice}");
    }
}

public class PriceLogger
{
    public void OnPriceChanged(decimal newPrice)
    {
        Console.WriteLine($"Logged: {newPrice}");
    }
}

מנויים מצרפים את המתודות שלהם לאירוע באמצעות += ויכולים להסיר אותן באמצעות -=:

var stock = new Stock();
var alert = new PriceAlert();
var logger = new PriceLogger();

stock.PriceChanged += alert.OnPriceChanged;
stock.PriceChanged += logger.OnPriceChanged;

stock.Price = 150.50m;
// פלט:
// התראה: המחיר כעת 150.50
// נרשם: 150.50

stock.PriceChanged -= logger.OnPriceChanged;  // ביטול הרשמה
stock.Price = 155.00m;
// פלט: התראה: המחיר כעת 155.00

תבנית Observer מעודדת צימוד רופף - המחלקה Stock לא צריכה לדעת דבר על הצופים שלה. צופים חדשים יכולים להירשם בלי לשנות את המפרסם, וכך קל להרחיב ולתחזק את המערכת.

challenge icon

אתגר

קל

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

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

  • TemperatureSensor.cs: צרו מחלקה TemperatureSensor במרחב השמות Monitoring. זהו המפרסם שלכם — הנושא שאובייקטים אחרים יצפו בו. לחיישן שלכם צריכים להיות:
    • שדה פרטי לאחסון הטמפרטורה הנוכחית
    • אירוע בשם TemperatureChanged שמשתמש ב-Action<double> כדי להודיע למנויים על הטמפרטורה החדשה
    • מאפיין Temperature שמפעיל את האירוע בכל פעם שהטמפרטורה מוגדרת לערך חדש
  • Observers.cs: צרו שתי מחלקות צופות באותו מרחב שמות, שיירשמו לעדכוני טמפרטורה:
    • DisplayUnit — כוללת מתודה OnTemperatureChanged(double temp) שמדפיסה Display: {temp}C
    • AlarmSystem — כוללת מתודה OnTemperatureChanged(double temp) שמדפיסה Alarm Check: {temp}C
  • Program.cs: חברו הכול יחד על ידי יצירת חיישן ושני הצופים. רשמו את שני הצופים לאירוע של החיישן, ואז עדכנו את הטמפרטורה. לאחר מכן, בטלו את הרישום של מערכת ההתראה ועדכנו שוב את הטמפרטורה כדי להראות שרק יחידת התצוגה מקבלת את ההודעה.

תקבלו שתי קלטים:

  • קריאת הטמפרטורה הראשונה (למשל, 22.5)
  • קריאת הטמפרטורה השנייה (למשל, 28.0)

התוכנית שלכם צריכה:

  1. ליצור את החיישן ואת שני הצופים
  2. לרשום את שני הצופים לאירוע TemperatureChanged
  3. להגדיר את טמפרטורת החיישן לערך הקלט הראשון (שני הצופים אמורים לקבל הודעה)
  4. לבטל את הרישום של AlarmSystem לאירוע
  5. להגדיר את טמפרטורת החיישן לערך הקלט השני (רק התצוגה אמורה לקבל הודעה)

לדוגמה, אם הקלטים הם 22.5 ו-28.0, הפלט אמור להיות:

Display: 22.5C
Alarm Check: 22.5C
Display: 28C

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

נסו בעצמכם

using System;
using Monitoring;

class Program
{
    public static void Main(string[] args)
    {
        // קרא את הטמפרטורות מהקלט
        double temp1 = Convert.ToDouble(Console.ReadLine());
        double temp2 = Convert.ToDouble(Console.ReadLine());

        // TODO: צור מופע של TemperatureSensor

        // TODO: צור מופעים של DisplayUnit ו-AlarmSystem

        // TODO: רשום את שני המשקיפים לאירוע TemperatureChanged

        // TODO: הגדר את טמפרטורת החיישן ל-temp1 (שני המשקיפים יקבלו הודעה)

        // TODO: בטל את הרישום של AlarmSystem לאירוע

        // TODO: הגדר את טמפרטורת החיישן ל-temp2 (רק DisplayUnit יקבל הודעה)
    }
}
quiz iconבחנו את עצמכם

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

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

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