Giriş

Bir nesnenin durumu değiştiğinde, bu değişikliği bir veya daha fazla başka nesneye otomatik olarak bildirmek istediğinizde Observer Pattern devreye girer. Örneğin; bir stok seviyesi azaldığında, hem e-posta hem SMS bildirimleri göndermek gibi senaryolarda kullanılır.

observer-pattern-uml-diyagrami

1. Observer Pattern Temel Kavramları

  • Subject (Observable): Durum değişikliklerini yöneten sınıf.
  • Observer: Subject’e kayıt olarak güncellemeleri alan sınıf.
  • register/deregister: Observer’ları ekleyip çıkarma metotları (Attach, Detach).
  • notify: Subject durum değiştiğinde tüm Observer’lara bildirim yollama.

2. Kurulum ve Temel Örnek

A. Subject Arayüzü

public interface ISubject
{
    void Attach(IObserver observer);
    void Detach(IObserver observer);
    void Notify();
}

B. Observer Arayüzü

public interface ISubject
{
    void Attach(IObserver observer);
    void Detach(IObserver observer);
    void Notify();
}

C. ConcreteSubject

public class Stock : ISubject
{
    private readonly List<IObserver> _observers = new();
    public string Symbol { get; }
    public decimal Price { get; private set; }

    public Stock(string symbol, decimal initialPrice)
    {
        Symbol = symbol;
        Price = initialPrice;
    }

    public void SetPrice(decimal newPrice)
    {
        Price = newPrice;
        Notify();
    }

    public void Attach(IObserver observer)    => _observers.Add(observer);
    public void Detach(IObserver observer)    => _observers.Remove(observer);
    public void Notify()                      => 
        _observers.ForEach(o => o.Update($"{Symbol} price changed to {Price}"));
}

D. ConcreteObserver’lar

public class EmailNotifier : IObserver
{
    public void Update(string message) => 
        Console.WriteLine($"[Email] {message}");
}

public class SmsNotifier : IObserver
{
    public void Update(string message) => 
        Console.WriteLine($"[SMS] {message}");
}

E. Kullanım

var stock = new Stock("ABC", 100m);
var email = new EmailNotifier();
var sms   = new SmsNotifier();

stock.Attach(email);
stock.Attach(sms);

stock.SetPrice(105m);
// Konsola: [Email] ABC price changed to 105
//          [SMS]   ABC price changed to 105

3. Katmanlı Mimari Entegrasyonu

Katman Rol
Domain ISubject, IObserver, Stock, Notifier
Application Abstraction ve servis yönetimi
API/UI Controller veya UI tetikleyici

observer-katmanli-mimari-semasi

4. Gelişmiş Senaryolar

A. Otomatik Kaydolma

public class AutoSubscriber : IObserver
{
    public AutoSubscriber(ISubject subject)
    {
        subject.Attach(this);
    }
    public void Update(string state) => Console.WriteLine($"[Auto] {state}");
}

B. Filtreli Bildirim

public class PriceThresholdNotifier : IObserver
{
    private readonly decimal _threshold;
    public PriceThresholdNotifier(ISubject subject, decimal threshold)
    {
        _threshold = threshold;
        subject.Attach(this);
    }

    public void Update(string state)
    {
        var price = decimal.Parse(state.Split(' ').Last());
        if (price > _threshold)
            Console.WriteLine($"[Threshold Alert] {state}");
    }
}

5. Avantajlar & Dezavantajlar

Avantajlar

  • Gevşek Bağlılık: Subject ve Observer arası düşük bağımlılık
  • Dinamik: Çalışma zamanında Observer ekleme/çıkarma
  • Çoklu Bildirim: Bir değişikliğe birden fazla tepki

Dezavantajlar

  • Yönetim Karmaşıklığı: Çok fazla Observer yönetimi
  • Olası Bellek Sızıntısı: Detach unutulursa referanslar kalabilir
  • Performans: Çok sayıda Observer’de bildirim maliyeti

İleri Okuma ve Kaynaklar

6. Sonuç

Observer Pattern, birden fazla öğeyi uyarmak istediğiniz senaryolarda ideal bir çözümdür. Doğru Attach/Detach yönetimi ve hafıza temizliği ile güvenle kullanabilirsiniz.

By tanju.bozok

Software Architect, Developer, and Entrepreneur

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir