在軟件構建過程中,需要為某些對象建立一種“通知依賴關系”,即一個對象的狀態發生改變,所有的依賴對象都需要得到通知。
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接口更為松耦合的設計。