1. 程式人生 > 其它 >淺談觀察者模式

淺談觀察者模式

淺談觀察者模式

觀察者模式

定義

指多個物件間存在一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。這種模式有時又稱作釋出-訂閱模式,它是物件行為型模式。

舉一個常見的例子

有這樣一個例子:

某些顧客對某商店的產品很感興趣(例如蘋果十三香),顧客可以每天來檢視是否到貨,大多數情況會空手而歸。
當然商店可以通知顧客到貨了,但是很可能被顧客認為故意騷擾。
我們可以讓感興趣的顧客(觀察者)告訴商店(釋出者),當十三香到貨了,商店(釋出者)就會通知顧客(觀察者)。

關鍵物件

釋出者:要將自身的狀態改變通知給其他物件.
觀察者:希望關注(訂閱)釋出者狀態變化的物件.

抽象

當顧客甲(觀察者 A)通過郵件方式告訴商店,顧客乙(觀察者 B)通過 XX 方式告訴商店,商店(釋出者)就會存在嚴重的資源浪費(釋出者不得不處理不同的訂閱方式)。
所以我們需要一個規範(觀察者介面)

主要物件

觀察者介面(Observer):它是一個抽象類或介面,它包含了一個更新自己的抽象方法,當接到Publisher的更改通知時被呼叫。
具體觀察者(Concrete Observer):實現抽象觀察者中介面定義的方法,以便在得到目標的更改通知時更新自身的狀態。
釋出者(Publisher):被觀察的目標,它實現通知方法,當內部狀態發生改變時,通知所有註冊過的觀察者物件。

C#簡單程式碼示例

點選檢視程式碼
//訂閱者
    public class Publisher
    {
        public List<IObserver> Observers { get; set; } = new List<IObserver>();


        //訂閱(這個方法名是為了好理解,一般方法名為Subscribe)
        //其實在觀察者模式中,由Publisher和observer實現訂閱都可以。
        public void AddObserver(IObserver observer)
        {
            Console.WriteLine($"Publisher: I'm Add {observer.GetType().Name}");
            this.Observers.Add(observer);
        }
        //取消訂閱(這個方法名是為了好理解,一般方法名為UnSubscribe)
        public void DeleteObserver(IObserver observer)
        {
            Console.WriteLine($"Publisher: I'm Delete {observer.GetType().Name}");
            this.Observers.Remove(observer);
        }

        //通知
        private void Notify()
        {
             Console.WriteLine("Publisher: 我到貨了");
            foreach (var item in Observers)
            {
                item.onGetNotify(this);
            }
        }

    }

    //觀察者介面(Observer)
    public interface IObserver
    {
        //收到通知時做出的反應(這個方法名是為了好理解,一般方法名為next)
        public void onGetNotify(Publisher publisher);
    }

    public class ObserverA : IObserver
    {
        public void onGetNotify(Publisher publisher)
        {
            System.Console.WriteLine($"{this.GetType().Name} 我知道了");
        }
    }

    public class ObserverB : IObserver
    {
        public void onGetNotify(Publisher publisher)
        {
            System.Console.WriteLine($"{this.GetType().Name} 我知道了");
        }
    }

呼叫程式碼

點選檢視程式碼
        var publisher = new Publisher();
        var observerA = new ObserverA();
        var observerB = new ObserverB();
        publisher.AddObserver(observerA);
        publisher.AddObserver(observerB);
        publisher.Notify();
        publisher.DeleteObserver(observerA);
        publisher.Notify();
        publisher.DeleteObserver(observerB);
        publisher.Notify();

執行結果:

.net中的Observe

.net中提供了兩個介面,方便開發者建立觀察者模式

IObserver<T> 提供用於接收基於推送的通知的機制。(釋出者)
IObservable<T> 定義基於推送的通知的提供程式。(觀察者)

MSDN文件非常詳盡我這裡就不一一贅述了。感興趣的可以看看[https://docs.microsoft.com/zh-cn/dotnet/api/system.iobserver-1?view=net-6.0]