什麼是觀察者模式?設計模式
摘自百度百科的說法:觀察者模式(有時又被稱爲發佈(publish )-訂閱(Subscribe)模式、模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式)是軟件設計模式的一種。在此種模式中,一個目標物件管理全部相依於它的觀察者物件,而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。此種模式一般被用來實現事件處理系統。函數
說白了,就是一個主題,能夠有N多個觀察者,一個觀察者,也能夠訂閱N多個主題。當一個主題,發生改變時,會通知訂閱它的觀察者,觀察者收到通知後,能夠作相應的處理。觀察者模式,是軟件設計模式中的一種。接下里,咱們介紹下,使用C#實現的觀察者模式。附上代碼。this
首先,咱們新建一個名爲AppObserver的控制檯項目。結構以下:spa
Strategy目錄下新建兩個接口,一個IObserver(觀察者)、一個ISubject(主題)。讓咱們看看,這兩個接口分別定義了什麼?設計
/* * Created by http://www.lichaoqiang.com * User: 李朝強 * Date: 2016/9/2 * Time: 16:25 * * To change this template use Tools | Options | Coding | Edit Standard Headers. */ using System; using System.Collections.Generic; namespace AppObserver.Strategy { /// <summary> /// Description of ISubject. /// </summary> public interface ISubject { /// <summary> /// 主題 /// </summary> string Title{get;set;} /// <summary> /// 觀察者 /// </summary> List<IObserver> Observers{get;} /// <summary> /// 添加訂閱 /// </summary> /// <param name="observer"></param> void AddObserver(IObserver observer); /// <summary> /// 發佈 /// </summary> void Publish(); } }
觀察者接口(IObserver):code
/* * Created by http://www.lichaoqiang.com * User: 李朝強 * Date: 2016/9/2 * Time: 16:27 * * To change this template use Tools | Options | Coding | Edit Standard Headers. */ using System; using System.Collections.Generic; namespace AppObserver.Strategy { /// <summary> /// Description of IObserver. /// </summary> public interface IObserver { /// <summary> /// 名稱 /// </summary> string Name{get;} /// <summary> /// 主題 /// </summary> List<ISubject> Subjects{get;} /// <summary> /// 通知 /// </summary> void Notify(ISubject subject); /// <summary> /// 訂閱 /// </summary> /// <param name="subject"></param> void Subscribe(ISubject subject); /// <summary> /// 取消訂閱 /// </summary> /// <param name="subject"></param> void Unsubscribe(ISubject subject); } }
接下來,新建一個Support文件夾,提供對以上兩個接口的實現。具體代碼以下:server
主題:htm
/* * Created by http://www.lichaoqiang.com * User: 李朝強 * Date: 2016/9/2 * Time: 16:34 * * To change this template use Tools | Options | Coding | Edit Standard Headers. */ using System; using System.Collections.Generic; using AppObserver.Strategy; namespace AppObserver.Support { /// <summary> /// Description of Subject. /// </summary> public class Subject:ISubject { /// <summary> /// 構造函數 /// </summary> public Subject() { Observers = new List<IObserver>(); } #region ISubject implementation /// <summary> /// 添加觀察者 /// </summary> /// <param name="observer"></param> void ISubject.AddObserver(IObserver observer) { Observers.Add(observer); } /// <summary> /// 發佈 /// </summary> void ISubject.Publish() { if (null != Observers && Observers.Count > 0) foreach (var item in Observers) {item.Notify(this);} } /// <summary> /// 主題 /// </summary> string ISubject.Title { get; set; } /// <summary> /// 觀察者 /// </summary> public List<IObserver> Observers { get; private set; } #endregion } }
觀察者:對象
/* * Created by http://www.lichaoqiang.com * User: 李朝強 * Date: 2016/9/2 * Time: 16:37 * * To change this template use Tools | Options | Coding | Edit Standard Headers. */ using System; using System.Collections.Generic; using AppObserver.Strategy; namespace AppObserver.Support { /// <summary> /// 觀察者 /// </summary> public class Observer:IObserver { /// <summary> /// 構造函數 /// </summary> public Observer() { Subjects = new List<ISubject>(); } /// <summary> /// 構造函數 /// </summary> /// <param name="name"></param> public Observer(String name) : this() { Name = name; } #region IObserver implementation /// <summary> /// 名字 /// </summary> public string Name{ get; private set; } /// <summary> /// 通知 /// </summary> void IObserver.Notify(ISubject subject) { //這裏具體能夠處理你的業務邏輯 //咱們能夠經過擴展suject對象,來傳遞信息 Console.WriteLine("【{0}】收到最新通知(Notify)主題:{1}", this.Name, subject.Title); } /// <summary> /// 訂閱 /// </summary> /// <param name="subject">主題</param> void IObserver.Subscribe(ISubject subject) { subject.AddObserver(this); Subjects.Add(subject); } /// <summary> /// 取消訂閱 /// </summary> /// <param name="subject">主題</param> void IObserver.Unsubscribe(ISubject subject) { } /// <summary> ///獲取已訂閱的主題 /// </summary> public List<ISubject> Subjects { get; private set; } #endregion } }
完成以上幾步,就簡單的實現了觀察者模式。讓咱們一塊兒來看看效果吧。接口
場景:張三和李四兩我的,一個愛好體育和娛樂,一個愛好體育。因而,張三,拿起IiPhone 6s plus,打開App,點擊並訂閱了《體育頻道》、《娛樂頻道》兩個欄目,李四看了,也立刻掏出小米5s,以迅雷不及掩耳盜鈴之勢,打開相同的APP,也一樣訂閱了《體育頻道》這檔欄目。就在這個時候,遠在千里以外的一座大都市,一個S身材的MZ,坐在辦公桌前,準備好了資訊內容,準備這個時候,向廣大粉絲,推送這些信息。因而,她先把準備好的體育信息,標題爲「張繼科XXXX」的主題,推送出去。而後,接着隔壁同事老王,負責《娛樂頻道》的有痣青年,把主題爲《王寶強XXXX》的信息,推送出去。這個時候,張三和李四的手機,不約而同的響起了一聲清脆的聲音。打開一看,效果以下:
張三和李四,頓時沉迷其中,認認真真的閱讀起了這些內容。
張3、李四虛構故事,以娛你們,博君一笑,夫復何求哈。