Menu
CoddyTech

Observer Kalıbı (Olaylar)

Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 54 / 70.

Observer kalıbı, bir nesnenin (özne) durumu değiştiğinde birden fazla bağımlı nesneyi (gözlemci) bilgilendirdiği bire-çok ilişkisi kurar. C# dilinde olaylar, bu kalıbı zarif bir şekilde uygulamak için yerleşik bir yol sunar.

Bu kalıp, olayları tetikleyen bir yayıncıyı ve bu olaylara yanıt veren aboneleri içerir. İşte hisse senedi fiyatı izleyicisine dair pratik bir örnek:

public class Stock
{
    private decimal _price;
    
    public event Action<decimal> PriceChanged;
    
    public decimal Price
    {
        get => _price;
        set
        {
            _price = value;
            PriceChanged?.Invoke(_price);  // Tüm gözlemcileri bilgilendir
        }
    }
}

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}");
    }
}

Aboneler, yöntemlerini olaya += kullanarak ekler ve -= kullanarak kaldırabilir:

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

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

stock.Price = 150.50m;
// Çıktı:
// Uyarı: Price artık 150.50
// Kaydedildi: 150.50

stock.PriceChanged -= logger.OnPriceChanged;  // Abonelikten çık
stock.Price = 155.00m;
// Çıktı: Uyarı: Price artık 155.00

Observer deseni, gevşek bağlılığı teşvik eder; Stock sınıfının gözlemcileri hakkında hiçbir şey bilmesi gerekmez. Yeni gözlemciler, yayıncı değiştirilmeden abone olabilir; bu da sistemi genişletmeyi ve bakımını kolaylaştırır.

challenge icon

Görev

Kolay

Olaylarla Observer kalıbını kullanarak bir sıcaklık izleme sistemi oluşturalım. Sıcaklık her değiştiğinde birden fazla gözlemciyi bilgilendiren bir sensör oluşturacaksın. Bu, farklı bileşenlerin sıcaklık güncellemelerine tepki vermesi gereken iklim kontrol sistemleri gibi senaryolar için idealdir.

Kodunu üç dosyaya ayıracaksın:

  • TemperatureSensor.cs: Monitoring ad alanında bir TemperatureSensor sınıfı oluştur. Bu, yayıncın; diğer nesnelerin gözlemleyeceği öznedir. Sensöründe şunlar bulunmalı:
    • Geçerli sıcaklığı saklamak için özel bir alan
    • Abonelere yeni sıcaklığı bildirmek için Action<double> kullanan TemperatureChanged adlı bir olay
    • Sıcaklık yeni bir değere ayarlandığında olayı tetikleyen bir Temperature özelliği
  • Observers.cs: Sıcaklık değişikliklerine abone olacak, aynı ad alanında iki gözlemci sınıfı oluştur:
    • DisplayUnit — Display: {temp}C yazdıran bir OnTemperatureChanged(double temp) metoduna sahiptir
    • AlarmSystem — Alarm Check: {temp}C yazdıran bir OnTemperatureChanged(double temp) metoduna sahiptir
  • Program.cs: Bir sensör ve iki gözlemci oluşturarak her şeyi bir araya getir. Her iki gözlemciyi de sensörün olayına abone et, ardından sıcaklığı güncelle. Sonra alarm sisteminin aboneliğini kaldır ve sıcaklığı tekrar güncelleyerek bildirimi yalnızca görüntü biriminin aldığını göster.

İki girdi alacaksın:

  • İlk sıcaklık ölçümü (ör. 22.5)
  • İkinci sıcaklık ölçümü (ör. 28.0)

Programın şunları yapmalı:

  1. Sensörü ve iki gözlemciyi oluşturmak
  2. Her iki gözlemciyi de TemperatureChanged olayına abone etmek
  3. Sensörün sıcaklığını ilk girdi değerine ayarlamak (iki gözlemci de bilgilendirilmeli)
  4. AlarmSystem sınıfının olay aboneliğini kaldırmak
  5. Sensörün sıcaklığını ikinci girdi değerine ayarlamak (yalnızca görüntü birimi bilgilendirilmeli)

Örneğin, girdiler 22.5 ve 28.0 ise çıktı şöyle olmalı:

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

Bu, Observer kalıbının temel gücünü gösterir: sensör, kendisini kimin dinlediğini bilmez ve bunu önemsemez. Gözlemciler dinamik olarak abone olabilir ve aboneliklerini kaldırabilir; yayıncı da yalnızca o anda kendisini dinleyenleri bilgilendirir!

Kendin dene

using System;
using Monitoring;

class Program
{
    public static void Main(string[] args)
    {
        // Giriş sıcaklıklarını oku
        double temp1 = Convert.ToDouble(Console.ReadLine());
        double temp2 = Convert.ToDouble(Console.ReadLine());

        // TODO: Bir TemperatureSensor örneği oluştur

        // TODO: DisplayUnit ve AlarmSystem örnekleri oluştur

        // TODO: Her iki gözlemciyi TemperatureChanged olayına abone et

        // TODO: Sensörün sıcaklığını temp1 olarak ayarla (her iki gözlemci de bilgilendirilir)

        // TODO: AlarmSystem aboneliğini olaydan kaldır

        // TODO: Sensörün sıcaklığını temp2 olarak ayarla (yalnızca ekran bilgilendirilir)
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online C# derleyicisi