定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。
簡而言之就是,觀察者模式能夠在被觀察者的某個指定動做執行時,通知到其對應的觀察者。使得觀察者們能夠即時作出相應的反應。
示例代碼的大概意圖其實就是實現一個下載器。當指定文件下載完成後,會通知其觀察者們,以便這些觀察者能夠根據各自需求處理下載下來的文件。c#
接下來,請見具體代碼。設計模式
/// <summary> /// 抽象觀察者 /// </summary> interface IObserver { void DoUpdate(); }
其實這個抽象觀察者,只是一個簡單的接口。全部具體觀察者都將繼承自它。spa
/// <summary> /// 具體觀察者-文件下載完成後,備份文件。 /// </summary> class Observer1 : IObserver { public void DoUpdate() { Console.WriteLine("觀察者1已將文件備份。"); } } /// <summary> /// 具體觀察者-文件下載完成後,壓縮文件。 /// </summary> class Observer2 : IObserver { public void DoUpdate() { Console.WriteLine("觀察者2已將文件壓縮。"); } } /// <summary> /// 具體觀察者-文件下載完成後,發送文件。 /// </summary> class Observer3 : IObserver { public void DoUpdate() { Console.WriteLine("觀察者3已將文件發送給相關同事。"); } }
以上是三個極簡的具體觀察者。它們分別在收到下載成功
的通知後,對文件進行備份,壓縮及轉發。設計
既然觀察者們已經準備好了,那麼該輪到被觀察者了。code
通常,被觀察者會相對複雜一點。由於它不僅僅要提供某動做的執行方法,也要提供註冊及註銷觀察者的方法。
當一個被觀察者被建立後,首先須要爲其綁定一些其必需的觀察者(若是須要的話)。觀察者們被綁定成功後,這個觀察者列表將被被觀察者維護着。
若被觀察者的某個動做執行完成後,若是須要通知觀察者,那麼就能夠經過這個觀察者列表,依次通知到全部須要被通知的觀察者。server
/// <summary> /// 文件下載器-被觀察者 /// </summary> class Downloader { /// <summary> /// 觀察者列表 /// </summary> public readonly HashSet<IObserver> observers; public Downloader() { observers = new HashSet<IObserver>(); } /// <summary> /// 註冊觀察者 /// </summary> public bool AddObserver(IObserver _observer) { return observers.Add(_observer); } /// <summary> /// 註銷觀察者 /// </summary> public bool RemoveObserver(IObserver _observer) { return observers.Remove(_observer); } /// <summary> /// 下載 /// </summary> public void Download() { Console.WriteLine("文件開始下載。"); Console.WriteLine("文件下載中···"); Thread.Sleep(3000);// 模擬文件下載的耗時過程 Console.WriteLine("文件下載完成。"); foreach (var observer in observers) { observer.DoUpdate(); } } }
如上代碼中,當Download
方法內,文件下載成功後,就會遍歷觀察者列表,逐個通知對應的觀察者,告訴它們:文件下載成功了,你該幹嗎幹嗎去
。對象
請看客戶端代碼blog
// 實例化下載器 var downloader = new Downloader(); // 建立觀察者 var o1 = new Observer1(); var o2 = new Observer2(); var o3 = new Observer3(); // 註冊觀察者 downloader.AddObserver(o1); downloader.AddObserver(o2); downloader.AddObserver(o3); // 下載 downloader.Download();
建立一個被觀察者對象,而後爲其註冊三個觀察者。註冊成功後,就能夠執行下載文件的動做了。
當文件下載完成後,Download
方法內部會自行通知已經成功註冊的觀察者們。繼承
如你所見,當文件下載完成
的通知發出後,各個觀察者就開始了它們各自的小動做,分別是備份,壓縮,轉發。接口
因爲觀察者們自己就有一個公共的抽象觀察者,這樣在某個觀察者須要變更時,大能夠廢棄掉這個觀察者,另起一個新的觀察者,而不用去對現有的任何觀察着作任何改動。所以從這個角度上講,觀察者模式是符合開閉原則的。
以上就是極簡版的觀察者模式的所有內容了。