在軟體構建過程中,需要為某些物件建立一種“通知依賴關係”,即一個物件的狀態發生改變,所有的依賴物件都需要得到通知。
1、觀察者模式簡介
1.1>、定義
定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。
1.2>、使用頻率
高
2、觀察者模式結構
2.1>、結構圖
2.2>、參與者
觀察者模式參與者:
◊ Subject
° 抽象的主題,被觀察的物件
° 提供Attach和Detach Observer物件的介面
◊ ConcreteSubject
° 具體的被觀察物件,維持ConcreteSubject狀態。
° 當狀態發生變化時,傳送訊息通知它的觀察者。
◊ Observer:抽象的觀察者,定義一個傳送變化通知更新的介面。
◊ ConcreteObserver
° 維持一個對ConcreteSubject物件的引用
° 儲存subjects狀態
° 實現當Observer介面發生變動時,subjects狀態同步更新。
在觀察者模式中,Subject通過Attach()和Detach()方法新增或刪除其所關聯的觀察者,並通過Notify進行更新,讓每個觀察者都可以觀察到最新的狀態。
3、觀察者模式結構實現
Observer.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.ObserverPattern.Structural { public abstract class Observer { public abstract void Update(); } }
Subject.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.ObserverPattern.Structural { public class Subject { private List<Observer> _observers = new List<Observer>(); public void Attach(Observer observer) { _observers.Add(observer); } public void Detach(Observer observer) { _observers.Remove(observer); } public void Notify() { foreach (Observer o in _observers) { o.Update(); } } } }
ConcreteSubject.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.ObserverPattern.Structural { public class ConcreteSubject : Subject { private string _subjectState; /// <summary> /// Gets or sets subject state /// </summary> public string SubjectState { get { return _subjectState; } set { _subjectState = value; } } } }
ConcreteObserver.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.ObserverPattern.Structural { public class ConcreteObserver : Observer { private string _name; private string _observerState; private ConcreteSubject _subject; public ConcreteObserver(ConcreteSubject subject, string name) { this._subject = subject; this._name = name; } public override void Update() { _observerState = _subject.SubjectState; Console.WriteLine("Observer {0}'s new state is {1}", _name, _observerState); } public ConcreteSubject Subject { get { return _subject; } set { _subject = value; } } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using DesignPatterns.ObserverPattern.Structural; namespace DesignPatterns.ObserverPattern { class Program { static void Main(string[] args) { // Configure Observer pattern ConcreteSubject s = new ConcreteSubject(); s.Attach(new ConcreteObserver(s, "X")); s.Attach(new ConcreteObserver(s, "Y")); s.Attach(new ConcreteObserver(s, "Z")); // Change subject and notify observers s.SubjectState = "ABC"; s.Notify(); } } }
執行輸出:
Observer X's new state is ABC Observer Y's new state is ABC Observer Z's new state is ABC 請按任意鍵繼續. . .
4、觀察者模式應用分析
觀察者模式適用情形:
◊ 當一個抽象模型有兩個方面,其中一方面依賴於另一方面。將這二者封裝在獨立的物件中以使它們可以各自獨立地改變和複用。
◊ 當對一個物件的改變需要同時改變其他物件,而不需要知道具體有多少物件有待改變。
◊ 當一個物件必須通知其他物件,而它又不需要知道其它的通知物件是誰,那些其它物件是誰不影響它傳送通知這件事。
觀察者模式特點:
◊ 使用物件導向的抽象,Observer模式使得可以獨立地改變目標與觀察者,從而使二者之間的依賴關係達到鬆耦合。
◊ 目標傳送通知時,無需指定觀察者,通知會自動傳播。觀察者自己決定是否需要訂閱通知。
◊ 在C#中的Event。委託充當了Observer介面,而提供事件的物件充當了目標物件,委託是比抽象Observer介面更為鬆耦合的設計。