.NET 提供原生支援,可大幅簡化觀察者模式實作,無需手動維護觀察者清單。
using System;
// 1. 定義委派:規範通知方法簽章
delegate void UpdateDelegate();
// 2. 主題角色
class Subject
{
public event UpdateDelegate UpdateHandler;
public void Attach(UpdateDelegate ud) => UpdateHandler += ud;
public void Detach(UpdateDelegate ud) => UpdateHandler -= ud;
public void Notify()
{
if (UpdateHandler != null) UpdateHandler();
}
}
// 3. 具體主題
class ConcreteSubject : Subject
{
private string subjectState;
public string SubjectState
{
get => subjectState;
set => subjectState = value;
}
}
// 4. 具體觀察者 A
class ConcreteObserver
{
private string name;
private string observerState;
private ConcreteSubject subject;
public ConcreteObserver(ConcreteSubject subject, string name)
{
this.subject = subject;
this.name = name;
}
public void Update()
{
observerState = subject.SubjectState;
Console.WriteLine($"Observer {name}'s new state is {observerState}");
}
}
// 5. 另一種觀察者:方法名不同也可訂閱
class AnotherObserver
{
public void Show() => Console.WriteLine("AnotherObserver got an Notification!");
}
// 6. 客戶端測試
public class Client
{
public static void Main()
{
ConcreteSubject s = new ConcreteSubject();
ConcreteObserver o1 = new ConcreteObserver(s, "1");
ConcreteObserver o2 = new ConcreteObserver(s, "2");
AnotherObserver o3 = new AnotherObserver();
s.Attach(new UpdateDelegate(o1.Update));
s.Attach(new UpdateDelegate(o2.Update));
s.Attach(new UpdateDelegate(o3.Show)); // 關鍵:Show() 也能訂閱!
s.SubjectState = "ABC";
s.Notify();
Console.WriteLine("--------------------------");
s.Detach(new UpdateDelegate(o1.Update)); // 移除 o1
s.SubjectState = "DEF";
s.Notify();
}
}
Observer 1's new state is ABC Observer 2's new state is ABC AnotherObserver got an Notification! -------------------------- Observer 2's new state is DEF AnotherObserver got an Notification!
Update(),任何符合委派簽章的方法皆可+=/-= 自動處理訂閱/取消訂閱event/delegateEventArgs 衍生類別