首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 觀察者模式完整實戰:從介面註冊到 .NET 事件委派的演進

     編輯:關於C#

模式本質:鬆耦合的訂閱–通知機制

觀察者模式定義物件間一對多依賴:主題(被觀察者)狀態變更時,自動通知所有觀察者。核心角色:

  • Subject(被觀察者):維護觀察者集合,提供註冊/移除/通知介面。
  • Observer(觀察者):實作通知回呼介面。

基礎實現:介面與容器

public interface IObserver {
    void Notify(object payload);
}
public interface IObservable {
    void Register(IObserver observer);
    void UnRegister(IObserver observer);
}

// 基礎主題實現
public class ObservableBase : IObservable {
    private readonly Hashtable _observers = new Hashtable(); // 鍵值同參考,利用鍵唯一性

    public void Register(IObserver o) => _observers.Add(o, o);
    public void UnRegister(IObserver o) => _observers.Remove(o);

    protected void NotifyObservers(object payload) {
        foreach (IObserver o in _observers.Keys)
            o.Notify(payload);
    }
}

具體業務範例:股價監控

// 被觀察者:股票資料
public class StockData : ObservableBase {
    private decimal _price;
    public decimal Price {
        get => _price;
        set {
            _price = value;
            NotifyObservers(_price); // 狀態變更即時通知
        }
    }
}

// 觀察者:UI 顯示
public class StockDisplay : IObserver {
    public void Notify(object payload) {
        Console.WriteLine($"價格更新:{payload:C}");
    }
}

// 使用
var data = new StockData();
var ui = new StockDisplay();
data.Register(ui);
data.Price = 100.5m;  // UI 自動收到通知
data.UnRegister(ui);  // 停止觀察

.NET 原生優化:事件與委派

C# event + delegate 是觀察者模式的語言級內建實現,省去手工管理集合:

public class StockData {
    // 宣告事件
    public event EventHandler PriceChanged;

    private decimal _price;
    public decimal Price {
        get => _price;
        set {
            if (_price != value) {
                _price = value;
                OnPriceChanged(new PriceChangedEventArgs(value));
            }
        }
    }

    protected virtual void OnPriceChanged(PriceChangedEventArgs e) {
        PriceChanged?.Invoke(this, e); // 安全引發
    }
}

public class PriceChangedEventArgs : EventArgs {
    public decimal NewPrice { get; }
    public PriceChangedEventArgs(decimal price) => NewPrice = price;
}

// 訂閱端
var data = new StockData();
data.PriceChanged += (s, e) => Console.WriteLine($"新價格:{e.NewPrice:C}");
data.Price = 200.0m;

對比優勢

維度手工介面實現.NET 事件/委派
樣板代碼多(集合管理、線程安全)極少
型別安全傳 object 需轉型強型別 EventArgs
多播支援手動迴圈內建 +=/-=
語法糖無Lambda、匿名方法、事件存取器
適用場景跨語言、非 .NET 環境、極度底層控制絕大多數 .NET 業務開發

進階主題

  • 弱事件模式:避免觀察者被主題強參考導致記憶體洩漏(WeakEventManager)。
  • 非同步通知:Task.Run(() => observer.Notify(payload)) 或 INotifyPropertyChanged 數據繫結。
  • Reactive Extensions (Rx):IObservable 將事件流轉為可組合、可查詢的資料流。

總結

觀察者模式是解耦的基石。.NET 開發者應優先使用 event/delegate,僅在特殊需求下手工實作。理解其內部機制,有助於診斷記憶體洩漏、死鎖與效能問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved