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

C# 設計模式:觀察者模式 (Observer Pattern) 事件通知機制實作

     編輯:關於C#

簡介

觀察者模式屬於行為型模式,定義了物件間的一對多依賴關係,當一個物件(主題/Subject)狀態改變時,所有依賴它的物件(觀察者/Observer)都會收到通知並自動更新。這是實現事件驅動架構、解耦發布者與訂閱者的經典模式。

核心角色

  • Subject (主題):維護觀察者清單,提供註冊/移除/通知介面(AbstractMessageSubject)。
  • ConcreteSubject (具體主題):實際狀態持有者,狀態變更時觸發通知(MessageSubject)。
  • Observer (觀察者):定義更新介面(IMessage)。
  • ConcreteObserver (具體觀察者):實作更新邏輯(SqlMessage, XmlMessage)。

實作範例:訊息插入操作的多通道通知

情境:當 MessageModel 發生變更(如發布時間更新),自動通知 SQL 與 XML 兩個通道執行插入操作。

1. 觀察者介面與實作

// 觀察者介面
public interface IMessage
{
    string Insert(MessageModel mm);
}

// SQL 觀察者
public class SqlMessage : IMessage
{
    public string Insert(MessageModel mm) => $"sql方式:{mm.Message} {mm.PublishTime}";
}

// XML 觀察者
public class XmlMessage : IMessage
{
    public string Insert(MessageModel mm) => $"xml方式:{mm.Message} {mm.PublishTime}";
}

2. 主題抽象與實作

using System.Collections.Generic;

public abstract class AbstractMessageSubject
{
    private readonly MessageModel _model;
    private readonly List<IMessage> _observers = new List<IMessage>();

    protected AbstractMessageSubject(MessageModel mm) { _model = mm; }

    public void Attach(IMessage observer) => _observers.Add(observer);
    public void Detach(IMessage observer) => _observers.Remove(observer);

    public string Notify()
    {
        var result = string.Empty;
        foreach (var obs in _observers)
        {
            result += obs.Insert(_model) + "<br />";
        }
        return result;
    }

    // 當 PublishTime 變更時自動通知
    public DateTime PublishTime
    {
        get => _model.PublishTime;
        set
        {
            _model.PublishTime = value;
            Notify(); // 狀態改變觸發通知
        }
    }
}

public class MessageSubject : AbstractMessageSubject
{
    public MessageSubject(MessageModel mm) : base(mm) { }
}

3. 客戶端測試

public partial class Observer : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var subject = new MessageSubject(new MessageModel("插入Message", DateTime.Now));

        var sqlObs = new SqlMessage();
        var xmlObs = new XmlMessage();

        subject.Attach(sqlObs);
        subject.Attach(xmlObs);

        // 手動觸發通知 (或透過修改 PublishTime 自動觸發)
        Response.Write(subject.Notify());

        // 若取消註解下行,將再次觸發通知
        // subject.PublishTime = DateTime.Now;
    }
}

執行結果

sql方式:插入Message 2007-5-26 9:38:18
xml方式:插入Message 2007-5-26 9:38:18

進階考量:.NET 事件模式

在現代 C# 開發中,觀察者模式通常直接使用內建的 event 與 delegate 機制,或 IObservable<T>/IObserver<T> (Reactive Extensions) 來實現,提供更優雅的語法與執行緒安全保障。但理解經典模式結構有助於掌握事件驅動架構的本質。

模式優缺點

優點缺點
主題與觀察者鬆耦合 觀察者過多時通知效能可能下降
支援廣播通訊 可能導致循環引用或記憶體洩漏 (需正確移除)
符合開放封閉原則 若觀察者邏輯複雜,除錯困難

適用場景

  • 單一物件狀態變更需通知多個其他物件。
  • 物件之間需鬆耦合,且動態增減訂閱關係。
  • 實作事件總線、訊息佇列、UI 數據綁定等。
觀察者模式類別圖

參考資料:DoFactory Observer Pattern

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