程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 觀察者模式(發布、訂閱)之(上) 李朝強 李朝強,觀察者李朝

觀察者模式(發布、訂閱)之(上) 李朝強 李朝強,觀察者李朝

編輯:C#入門知識

觀察者模式(發布、訂閱)之(上) 李朝強 李朝強,觀察者李朝


什麼是觀察者模式?

摘自百度百科的說法:觀察者模式(有時又被稱為發布(publish )-訂閱(Subscribe)模式、模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式)是軟件設計模式的一種。在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。

 說白了,就是一個主題,可以有N多個觀察者,一個觀察者,也可以訂閱N多個主題。當一個主題,發生改變時,會通知訂閱它的觀察者,觀察者收到通知後,可以做相應的處理。觀察者模式,是軟件設計模式中的一種。接下裡,我們介紹下,使用C#實現的觀察者模式。附上代碼。

      首先,我們新建一個名為AppObserver的控制台項目。結構如下:

 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):

/*
 * 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文件夾,提供對以上兩個接口的實現。具體代碼如下:

主題:

/*
 * 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》的信息,推送出去。這個時候,張三和李四的手機,不約而同的響起了一聲清脆的聲音。打開一看,效果如下:

張三和李四,頓時沉迷其中,認認真真的閱讀起了這些內容。

 張三、李四虛構故事,以娛大家,博君一笑,夫復何求哈。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved