**定義:**觀察者模式(ObserverPattern),定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。
類型:對象行為型模式
概述:
????????觀察者模式也是比較難以理解,單看類圖,會發現觀察者模式與中介模式非常相似。如果不真正理解他們二者之間的區別,是難以真正理解觀察者模式的。如果不理解觀察者模式,更奢談運用觀察者模式了。
????????中介模式主要是解決一系列交互對象的耦合的問題,而提出了中介類。幾個以前交互的對象現在統一通過中介類來完成交流。而觀察者模式側重的是一對多的通知的功能,即當發生某件事時,主題對象將向所有注冊過的觀察者對象發出通知消息。
????????中介模式側重通過中介類來完成交流;而觀察者模式側重于一對多的通知。中介模式不需要知道具體的中介類的對象,需要交互的對象只需要知道一個通知中介對象的接口即可,具體是哪個中介來完成交互對象告訴的任務,交互對象不需要知道。但是交互對象必須知道有哪些交互對象,這樣才能把對象A需要對象B做的事想辦法通知到對象B。
?????????觀察者模式則,Subject對象不需要知道具體的觀察者是誰,它只需要知道觀察者的通知接口,就可以將消息通知到觀察者。至于具體有哪些消息,則需要觀察者自己去具體的Subject那里查看。
?????????這里舉一個例子,某電商有大促銷,通過郵件發送促銷消息給消費者。但是如果消費者想了解有哪些具體的促銷信息,則即需要親自去電商網站查看有哪些具體的促銷信息。
類圖:

**參與者:**
1. Vender,提供接口來完成對觀察者的注冊通知。
1. YiXun,具體的電商,為消費者提供所需要查看具體信息。
1. Observer,提供Update接口。
1. CustomerA、CustomerB,具體的觀察者,當有更新時去查看電商中自己喜歡的產品。
**示例代碼:**
~~~
using?System;
using?System.Collections.Generic;
using?System.Text;
namespace?Design20
{
???abstract?class?Vender
???{
???????private?IList<Observer>?observers?=?new?List<Observer>();
???????//?觀察者注冊
???????public?void?Register(Observer?observer)
???????{
???????????observers.Add(observer);
???????}
???????//通知
???????public?void?Notify()
???????{
???????????foreach?(Observer?o?in?observers)
???????????{
???????????????o.Update();
???????????}
???????}
???}
???//具體通知者
???class?YiXun?:?Vender
???{
???????private?string?subjecPhone;
???????private?string?subjecLaptop;
???????//具體通知者狀態
???????public?string?SubjecPhone
???????{
???????????get?{?return?subjecPhone;?}
???????????set?{?subjecPhone?=?value;?}
???????}
???????//具體通知者狀態
???????public?string?SubjecLaptop
???????{
???????????get?{?return?subjecLaptop;?}
???????????set?{?subjecLaptop?=?value;?}
???????}
???}
???abstract?class?Observer
???{
???????public?abstract?void?Update();
???}
???class?CustomerA?:?Observer
???{
???????private?YiXun?subject;
???????public?CustomerA(
?????????YiXun?subject)
???????{
???????????this.subject?=?subject;
???????}
???????//更新
???????public?override?void?Update()
???????{
???????????Console.WriteLine("消費者A查看到的是{0}",?this.subject.SubjecPhone);
???????}
???????public?YiXun?Subject
???????{
???????????get?{?return?subject;?}
???????????set?{?subject?=?value;?}
???????}
???}
???class?CustomerB?:?Observer
???{
???????private?YiXun?subject;
???????public?CustomerB(
?????????YiXun?subject)
???????{
???????????this.subject?=?subject;
???????}
???????//更新
???????public?override?void?Update()
???????{
???????????Console.WriteLine("消費者B查看到的是{0}",?this.subject.SubjecLaptop);
???????}
???????public?YiXun?Subject
???????{
???????????get?{?return?subject;?}
???????????set?{?subject?=?value;?}
???????}
???}
???class?Program
???{
???????static?void?Main(string[]?args)
???????{
???????????YiXun?subject?=?new?YiXun();
???????????subject.Register(new?CustomerA(subject));
???????????subject.Register(new?CustomerB(subject));
???????????//?來了新手機和新筆記本電腦,然后通知到所有注冊的消費者.
???????????//?然后消費者去查看自己感興趣的產品有哪些.
???????????subject.SubjecPhone?=?"IPhone5s";
???????????subject.SubjecLaptop?=?"ThinkPad";
???????????subject.Notify();
???????????Console.Read();
???????}
???}
}
~~~
**適用性:**
1. ?一組對象以定義良好但是復雜的方式進行通信。產生的相互依賴關系結構混亂且難以理解。
1. 一個對象引用其他很多對象并且直接與這些對象通信,導致難以復用該對象。
1. 想定制一個分布在多個類中的行為,而又不想生成太多的子類。
優缺點:
1. 優點,降低命令發起者與命令接受者之間的耦合,發布者通過接口通知所有觀察者。
1. 缺點,具體的觀察者依賴了具體的發布者。
參考資料:
1. 《設計模式——可復用面向對象軟件基礎》
1. 《大話設計模式》
- 前言
- 設計模式六大原則
- 1——創建型模式之簡單工廠模式
- 2——創建型模式之工廠方法模式
- 3——創建型模式之抽象工廠模式
- 4——創建型模式之單例模式
- 5——創建型模式之建造者模式
- 6——創建型模式之原型模式
- 7——結構型模式之適配器模式
- 8——結構型模式之橋接模式
- 9——結構型模式之組合模式
- 10——結構型模式之裝飾者模式
- 11——結構型模式之外觀模式
- 12——結構型模式之享元模式
- 13——結構型模式之代理模式
- 14——行為型模式之職責鏈模式
- 15——行為型模式之命令模式
- 16——行為型模式之解釋器模式
- 17——行為型模式之迭代器模式
- 18——行為型模式之中介者模式
- 19——行為型模式之備忘錄模式
- 20——行為型模式之觀察者模式
- 21——行為型模式之狀態模式
- 22——行為型模式之策略模式
- 23——行為型模式之模板方法模型
- 24——行為型模式之訪問者模式
- 設計模式總結