概述
觀察者模式定義一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題,這個主題對象在狀態變化時,會通知所有的觀察者對象,使它們能夠自動更新自己。
結構圖
對應的代碼
class Program { static void Main(string[] args) { ConcreteSubject s = new ConcreteSubject(); s.Attach(new ConcreteObserver(s, "X")); s.Attach(new ConcreteObserver(s, "Y")); s.Attach(new ConcreteObserver(s, "Z")); s.SubjectState = "ABC"; s.Notify(); Console.Read(); } } abstract class Subject { private IList<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(); } } } //具體通知者 class ConcreteSubject : Subject { private string subjectState; //具體通知者狀態 public string SubjectState { get { return subjectState; } set { subjectState = value; } } } abstract class Observer { public abstract void Update(); } 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("觀察者{0}的新狀態是{1}", name, observerState); } public ConcreteSubject Subject { get { return subject; } set { subject = value; } } }
運行結果
生活中執行個體
1:例如:我門很多人在網上關注了一台智能手機(蘋果的),當手機的價格等任何狀態改變時,蘋果公司都會通過電話簡訊、郵件、告之我們客戶
2:在一個快遞公司來了很多包裹,工作人員發簡訊、打電話通知我們去那快遞等。
3:銀行卡在自助終端取錢時取了錢,銀行會通過簡訊、郵件方式提醒我們等等生活中有很多這樣的執行個體。
用事件和委託來實現Observer模式我認為更加的簡單和優雅,也是一種更好的解決方案。
在觀察者模式中我們不能緊緊依賴一個固定的觀察者來通知自己發生變化後引起依賴它的對象的狀態的改變,進一步的深入學習我們引入事件委託來解決問題。下面的例子簡單的用事件和委託實現如下,僅供大家參考:
class Program { static void Main(string[] args) { //老闆胡漢三 Boss huhansan = new Boss(); //看股票的同事 StockObserver tongshi1 = new StockObserver("魏關姹", huhansan); //看NBA的同事 NBAObserver tongshi2 = new NBAObserver("易管查", huhansan); huhansan.Update += new EventHandler(tongshi1.CloseStockMarket); huhansan.Update += new EventHandler(tongshi2.CloseNBADirectSeeding); //將兩個不同類的不同方法委託給老闆類的更新了 //老闆回來 huhansan.SubjectState = "我胡漢三回來了!"; //發出通知 huhansan.Notify(); Console.Read(); } } //通知者介面 interface Subject { void Notify(); string SubjectState { get; set; } } //事件處理常式的委託 delegate void EventHandler(); class Secretary : Subject { //聲明一事件Update,類型為委託EventHandler public event EventHandler Update; private string action; public void Notify() { Update(); } public string SubjectState { get { return action; } set { action = value; } } } class Boss : Subject { //聲明一事件Update,類型為委託EventHandler public event EventHandler Update; //聲明一EventHandler事件處理常式的委託事件,名稱為Update更新 private string action; public void Notify() { Update();//在訪問通知方法時,調用更新 } public string SubjectState { get { return action; } set { action = value; } } } //看股票的同事 class StockObserver { private string name; private Subject sub; public StockObserver(string name, Subject sub) { this.name = name; this.sub = sub; } //關閉股票行情 public void CloseStockMarket()//方法“更新”名改為“關閉股票程式” { Console.WriteLine("{0} {1} 關閉股票行情,繼續工作!", sub.SubjectState, name); } } //看NBA的同事 class NBAObserver { private string name; private Subject sub; public NBAObserver(string name, Subject sub) { this.name = name; this.sub = sub; } //關閉NBA直播 public void CloseNBADirectSeeding()//方法改為關閉NBA直播 { Console.WriteLine("{0} {1} 關閉NBA直播,繼續工作!", sub.SubjectState, name); } }使用觀察者模式的時機
1:當一個抽象模型有兩個方面,其中一個方面依賴於另一方面,這將二者封裝在獨立的對象中以使它們可以各自獨立地改變和複用。
2:當一個對象的改變同時改變其他對象,而不知道具體有多少對象有待改變。
3:當一個對象必須通知其他對象,而它又不能假定其他對象是誰,換言之,不希望這些對象是緊密耦合的。
總結
通過Observer Pattern模式,把一對多個物件之間的通知依賴關係的變得更為鬆散,大大地提高了程式的可維護性和可擴充性,也很好的符合了開放-封閉原則。