觀察者模式定義物件間一對多依賴,當主題 (Subject) 狀態改變,自動通知所有觀察者 (Observer)。C# 內建委派與事件關鍵字,原生支援此模式。
Attach/Detach/Notify,本範例為 CCollection。BusinessObject。CItem。public class CItem : EventArgs {
public readonly string Key;
public readonly long Value;
public CItem(string key, long value) { Key = key; Value = value; }
}
public class CCollection {
// 定義委派簽章:sender + 事件資料
public delegate void AddNewItem(object sender, CItem e);
// 宣告事件
public event AddNewItem OnAddItem;
public void AddItem(string key, long value) {
var item = new CItem(key, value);
// 觸發事件 (null 條件運算子防無訂閱者)
OnAddItem?.Invoke(this, item);
}
}
public class BusinessObject {
private readonly CCollection _collection;
public BusinessObject(CCollection collection) {
_collection = collection;
// 訂閱事件:指定回呼方法
_collection.OnAddItem += Collection_OnAddItem;
}
private void Collection_OnAddItem(object sender, CItem e) {
Console.WriteLine($"BusinessObject 收到通知:Key={e.Key}, Value={e.Value}");
// 更新內部資料結構...
}
public void Detach() {
_collection.OnAddItem -= Collection_OnAddItem;
}
}
class Program {
static void Main() {
var collection = new CCollection();
var bo1 = new BusinessObject(collection);
var bo2 = new BusinessObject(collection);
collection.AddItem("Order_001", 100); // 兩個 BO 皆收到通知
collection.AddItem("Order_002", 200);
bo1.Detach();
collection.AddItem("Order_003", 300); // 僅 bo2 收到
}
}
public interface IObserver{ void OnNext(T value); void OnError(Exception error); void OnCompleted(); } public class Subject { private readonly List > _observers = new(); public IDisposable Subscribe(IObserver observer) { _observers.Add(observer); return new Unsubscriber(_observers, observer); } public void Notify(T value) { foreach (var obs in _observers.ToArray()) obs.OnNext(value); } // ... OnError, OnCompleted, Unsubscriber 實作省略 }
此模式為 IObservable<T>/IObserver<T> (Reactive Extensions) 基礎。
C# delegate + event 讓觀察者模式實作極為簡潔:主題宣告事件、觀察者以 += 訂閱、主題以 Invoke 發佈。掌握此模式可構建鬆耦合、可擴充的事件驅動架構。