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

C# 觀察者模式另一種實作:介面與清單管理的傳統 GoF 風格

     編輯:關於C#

傳統 GoF 結構圖

Subject (介面)          Observer (介面)
    ▲                       ▲
    │                       │
ConcreteSubject       ConcreteObserver
- observers: List     - subject: Subject
- Attach/Detach       - Update()
- Notify()

完整程式碼實作


using System;
using System.Collections;

namespace ObserverGoF
{
    // 1. 觀察者介面
    public interface IObserver
    {
        void Update(int number);
    }

    // 2. 主題介面
    public interface ISubject
    {
        void Attach(IObserver observer);
        void Detach(IObserver observer);
        void Notify();
    }

    // 3. 具體主題
    public class Subject : ISubject
    {
        private ArrayList _observers = new ArrayList();
        private int _state;

        public int State
        {
            get => _state;
            set
            {
                _state = value;
                Notify(); // 狀態變更自動通知
            }
        }

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

        public void Notify()
        {
            foreach (IObserver o in _observers)
                o.Update(_state);
        }
    }

    // 4. 具體觀察者 A
    public class ObserverA : IObserver
    {
        public void Update(int number)
        {
            Console.WriteLine($"[ObserverA] 收到狀態變更:{number}");
        }
    }

    // 5. 具體觀察者 B
    public class ObserverB : IObserver
    {
        private string _name;
        public ObserverB(string name) => _name = name;

        public void Update(int number)
        {
            Console.WriteLine($"[{_name}] 處理數字:{number * 2}");
        }
    }

    // 6. 用戶端
    class Program
    {
        static void Main()
        {
            var subject = new Subject();
            subject.Attach(new ObserverA());
            subject.Attach(new ObserverB("ObserverB"));

            Console.WriteLine("設定狀態 = 10");
            subject.State = 10;

            Console.WriteLine("\n設定狀態 = 20");
            subject.State = 20;

            Console.ReadKey();
        }
    }
}

與 .NET Event 模式比較

維度GoF 介面式.NET Event/Delegate
型別安全需轉型或泛型介面原生強型別
多播支援手動管理清單內建 +=/-=
語法簡潔度較繁瑣語言級關鍵字
序列化/遠端易於序列化傳遞事件不可序列化
適用場景跨語言、需持久化訂閱關係一般 .NET 內部事件驅動

進階強化:泛型介面版


public interface IObserver { void OnNext(T value); }
public interface ISubject
{
    IDisposable Subscribe(IObserver observer);
    // 回傳 IDisposable 方便取消訂閱 (Rx 風格)
}

public class EventSubject : ISubject
{
    private readonly List> _observers = new();
    public IDisposable Subscribe(IObserver observer)
    {
        _observers.Add(observer);
        return new Unsubscriber(_observers, observer);
    }
    public void Notify(T value) => _observers.ForEach(o => o.OnNext(value));

    private sealed class Unsubscriber : IDisposable
    {
        private List> _list; private IObserver _obs;
        public Unsubscriber(List> list, IObserver obs) => (_list, _obs) = (list, obs);
        public void Dispose() => _list?.Remove(_obs);
    }
}

總結

GoF 介面式觀察者模式雖較繁瑣,但概念純粹、跨平台通用、易於序列化與單元測試。在 .NET 生態系內,優先使用 `event`/`delegate`;需跨進程、跨語言、或建構類 Rx 流式處理管線時,介面式設計更具彈性。

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