觀察者模式(發佈、訂閱)之(上)

什麼是觀察者模式?設計模式

摘自百度百科的說法:觀察者模式(有時又被稱爲發佈(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、李四虛構故事,以娛你們,博君一笑,夫復何求哈。

相關文章
相關標籤/搜索