C#設計模式--觀察者模式(發布-訂閱模式)
阿新 • • 發佈:2017-05-24
工廠方法 設計 解決 line strac itl names spa ret
0.C#設計模式--簡單工廠模式
1.C#設計模式--工廠方法模式
2.C#設計模式--抽象工廠模式
3.C#設計模式--單例模式
4.C#設計模式--建造者模式
5.C#設計模式--原型模式
6.C#設計模式--設配器模式
7.C#設計模式--裝飾器模式
8.C#設計模式--代理模式
9.C#設計模式--外觀模式
10.C#設計模式--橋接模式
設計模式:
觀察者模式(Observer Pattern)
簡單介紹:
觀察者模式(Observer Pattern)是設計模式中行為模式的一種,它解決了上述具有一對多依賴關系的對象的重用問題。此模式的參與者分為兩大類,一類是被觀察的目標,另一類是觀察該目標的觀察者們。正因為該模式是基於“一對多”的關系,所以該模式一般是應用於由一個目標對象和N個觀察者對象組成(當然也可以擴展為有多個目標對象,但我們現在只討論前者)的場合。當目標對象的狀態發生改變或做出某種行為時,正在觀察該目標對象的觀察者們將自動地、連鎖地作出相應的響應行為。
模式中具有的角色
- 抽象主題(Subject):它把所有觀察者對象的引用保存到一個聚集裏,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象。
- 具體主題(ConcreteSubject):將有關狀態存入具體觀察者對象;在具體主題內部狀態改變時,給所有登記過的觀察者發出通知。
- 抽象觀察者(Observer):為所有的具體觀察者定義一個接口,在得到主題通知時更新自己。
- 具體觀察者(ConcreteObserver):實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題狀態協調。
舉例子:博客的例子就是一個觀察者模式,比如你關註一些作者的博客,當作者有博客發布時候,你就會收到一條該作者發布的博客的消息。
抽象主題:Blog 博客
具體主題:JiYFBlog 的博客
抽象觀察者:IObserver
具體的觀察者:Observer
觀察者模式類圖:
觀察者模式C#代碼舉例
訂閱博客抽象類
1 /***************************************************** 2 * ProjectName: _11DesignPattern_Observer 3 * Description: 4 * ClassName: Blog 5 * CLRVersion: 4.0.30319.18408 6 * Author: JiYF7 * NameSpace: _11DesignPattern_Observer 8 * MachineName: JIYONGFEI 9 * CreateTime: 2017/5/23 17:08:10 10 * UpdatedTime: 2017/5/23 17:08:10 11 *****************************************************/ 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 using System.Text; 16 17 namespace _11DesignPattern_Observer 18 { 19 /// <summary> 20 /// 訂閱博客抽象類 21 /// </summary> 22 public abstract class Blog 23 { 24 /// <summary> 25 /// 保存訂閱者列表 26 /// </summary> 27 private List<IObserver> observers = new List<IObserver>(); 28 29 /// <summary> 30 /// 博主名 31 /// </summary> 32 public string BlogName { get; set; } 33 34 /// <summary> 35 /// 博客標題 36 /// </summary> 37 public string BlogTitle { get; set; } 38 39 /// <summary> 40 /// 博客信息 41 /// </summary> 42 public string BlogInfo { get; set; } 43 44 /// <summary> 45 /// 博客構造函數 46 /// </summary> 47 /// <param name="blogTitle">博客標題</param> 48 /// <param name="blogInfo">博客信息</param> 49 public Blog(string name,string blogTitle,string blogInfo) 50 { 51 this.BlogName = name; 52 this.BlogTitle = blogTitle; 53 this.BlogInfo = blogInfo; 54 } 55 56 /// <summary> 57 /// 添加一個訂閱者 58 /// </summary> 59 /// <param name="observer">具體的訂閱者對象</param> 60 public void AddObserver(IObserver observer) 61 { 62 if (observers.Contains(observer)) 63 { 64 return; 65 } 66 observers.Add(observer); 67 } 68 69 /// <summary> 70 /// 刪除一個訂閱者 71 /// </summary> 72 /// <param name="observer">具體的訂閱者對象</param> 73 public void RemoveObserver(IObserver observer) 74 { 75 if (observers.Contains(observer)) 76 { 77 observers.Remove(observer); 78 } 79 } 80 81 /// <summary> 82 /// 發布博客通知 83 /// </summary> 84 public void PublishBlog() 85 { 86 //遍歷通知每一個訂閱者 87 foreach (IObserver ob in observers) 88 { 89 if (ob != null) 90 { 91 ob.Receive(this); 92 } 93 } 94 } 95 96 } 97 }
具體的博客類
1 /***************************************************** 2 * ProjectName: _11DesignPattern_Observer 3 * Description: 4 * ClassName: JiYFBlog 5 * CLRVersion: 4.0.30319.18408 6 * Author: JiYF 7 * NameSpace: _11DesignPattern_Observer 8 * MachineName: JIYONGFEI 9 * CreateTime: 2017/5/23 17:21:23 10 * UpdatedTime: 2017/5/23 17:21:23 11 *****************************************************/ 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 using System.Text; 16 17 namespace _11DesignPattern_Observer 18 { 19 20 /// <summary> 21 /// 具體的訂閱博客類 22 /// </summary> 23 public class JiYFBlog :Blog 24 { 25 public JiYFBlog(string name,string blogTitile, string blogInfo) 26 : base(name,blogTitile,blogInfo) 27 { 28 29 } 30 } 31 }
訂閱者接口類
1 /***************************************************** 2 * ProjectName: _11DesignPattern_Observer 3 * Description: 4 * ClassName: IObserver 5 * CLRVersion: 4.0.30319.18408 6 * Author: JiYF 7 * NameSpace: _11DesignPattern_Observer 8 * MachineName: JIYONGFEI 9 * CreateTime: 2017/5/23 17:09:28 10 * UpdatedTime: 2017/5/23 17:09:28 11 *****************************************************/ 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 using System.Text; 16 17 namespace _11DesignPattern_Observer 18 { 19 /// <summary> 20 /// 訂閱者接口 21 /// </summary> 22 public interface IObserver 23 { 24 25 void Receive(Blog blog); 26 } 27 }
具體的訂閱者類:
1 /***************************************************** 2 * ProjectName: _11DesignPattern_Observer 3 * Description: 4 * ClassName: Observer 5 * CLRVersion: 4.0.30319.18408 6 * Author: JiYF 7 * NameSpace: _11DesignPattern_Observer 8 * MachineName: JIYONGFEI 9 * CreateTime: 2017/5/23 17:23:36 10 * UpdatedTime: 2017/5/23 17:23:36 11 *****************************************************/ 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 using System.Text; 16 17 namespace _11DesignPattern_Observer 18 { 19 /// <summary> 20 /// 具體的訂閱者類 21 /// </summary> 22 public class Observer :IObserver 23 { 24 /// <summary> 25 /// 訂閱者名字 26 /// </summary> 27 private string m_Name; 28 public string Name 29 { 30 get { return m_Name; } 31 set { m_Name = value; } 32 } 33 34 /// <summary> 35 /// 訂閱者構造函數 36 /// </summary> 37 /// <param name="name">訂閱者名字</param> 38 public Observer(string name) 39 { 40 this.m_Name = name; 41 } 42 43 /// <summary> 44 /// 訂閱者接受函數 45 /// </summary> 46 /// <param name="blog"></param> 47 public void Receive(Blog blog) 48 { 49 Console.WriteLine("訂閱者:\"{0}\"觀察到了:{1}發布的一篇博客,標題為:{2},內容為:{3}",Name,blog.BlogName,blog.BlogTitle,blog.BlogInfo); 50 } 51 } 52 }
測試代碼:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace _11DesignPattern_Observer 7 { 8 class Client 9 { 10 static void Main(string[] args) 11 { 12 Console.WriteLine("--全部訂閱者--"); 13 //創建一個JiYF的博客 14 Blog jiyfBlog = new JiYFBlog("JiYF笨小孩","醜小鴨","醜小鴨的故事"); 15 16 //創建訂閱者 17 Observer obsZhangsan = new Observer("張三"); 18 Observer obsLiSi = new Observer("李四"); 19 Observer obsWangwu = new Observer("王五"); 20 21 //添加對JiYF博客的訂閱者 22 jiyfBlog.AddObserver(obsZhangsan); 23 jiyfBlog.AddObserver(obsLiSi); 24 jiyfBlog.AddObserver(obsWangwu); 25 26 //通知訂閱者 27 jiyfBlog.PublishBlog(); 28 29 Console.WriteLine("--移除訂閱者張三--"); 30 jiyfBlog.RemoveObserver(obsZhangsan); 31 jiyfBlog.PublishBlog(); 32 Console.ReadLine(); 33 } 34 } 35 }
運行結果:
通常在C#代碼中,觀察者模式一般采用委托來實現如下所示
委托實現觀察者模式
抽象博客類:
1 /***************************************************** 2 * ProjectName: _11DesignPattern_ObserverDelegateTest 3 * Description: 4 * ClassName: Blog 5 * CLRVersion: 4.0.30319.42000 6 * Author: JiYF 7 * NameSpace: _11DesignPattern_ObserverDelegateTest 8 * MachineName: JIYF_PC 9 * CreateTime: 2017/5/23 20:48:00 10 * UpdatedTime: 2017/5/23 20:48:00 11 *****************************************************/ 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 using System.Text; 16 17 namespace _11DesignPattern_ObserverDelegateTest 18 { 19 /// <summary> 20 /// 委托充當訂閱者接口類 21 /// </summary> 22 /// <param name="sender"></param> 23 public delegate void NotifyEventHandler(object sender); 24 25 /// <summary> 26 /// 訂閱博客基類 27 /// </summary> 28 public class Blog 29 { 30 public NotifyEventHandler NotifyEvent; 31 /// <summary> 32 /// 博主名 33 /// </summary> 34 public string BlogName { get; set; } 35 36 /// <summary> 37 /// 博客標題 38 /// </summary> 39 public string BlogTitle { get; set; } 40 41 /// <summary> 42 /// 博客信息 43 /// </summary> 44 public string BlogInfo { get; set; } 45 46 /// <summary> 47 /// 博客構造函數 48 /// </summary> 49 /// <param name="blogTitle">博客標題</param> 50 /// <param name="blogInfo">博客信息</param> 51 public Blog(string name, string blogTitle, string blogInfo) 52 { 53 this.BlogName = name; 54 this.BlogTitle = blogTitle; 55 this.BlogInfo = blogInfo; 56 } 57 58 /// <summary> 59 /// 綁定訂閱事件 60 /// </summary> 61 /// <param name="ob">訂閱者</param> 62 public void AddObserver(NotifyEventHandler observer) 63 { 64 NotifyEvent += observer; 65 } 66 67 /// <summary> 68 /// 取消綁定訂閱 69 /// </summary> 70 /// <param name="observer"></param> 71 public void RemoteObserver(NotifyEventHandler observer) 72 { 73 NotifyEvent -= observer; 74 } 75 76 /// <summary> 77 /// 發布博客通知 78 /// </summary> 79 public void PublishBlog() 80 { 81 if(NotifyEvent != null) 82 { 83 NotifyEvent(this); 84 } 85 } 86 } 87 }
具體的博客類
1 /***************************************************** 2 * ProjectName: _11DesignPattern_ObserverDelegateTest 3 * Description: 4 * ClassName: JiYFBlog 5 * CLRVersion: 4.0.30319.42000 6 * Author: JiYF 7 * NameSpace: _11DesignPattern_ObserverDelegateTest 8 * MachineName: JIYF_PC 9 * CreateTime: 2017/5/23 20:55:58 10 * UpdatedTime: 2017/5/23 20:55:58 11 *****************************************************/ 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 using System.Text; 16 17 namespace _11DesignPattern_ObserverDelegateTest 18 { 19 /// <summary> 20 /// 具體的訂閱博客類 21 /// </summary> 22 public class JiYFBlog : Blog 23 { 24 public JiYFBlog(string name, string blogTitile, string blogInfo) 25 : base(name, blogTitile, blogInfo) 26 { 27 28 } 29 } 30 }
訂閱者類
1 /***************************************************** 2 * ProjectName: _11DesignPattern_ObserverDelegateTest 3 * Description: 4 * ClassName: Observer 5 * CLRVersion: 4.0.30319.42000 6 * Author: JiYF 7 * NameSpace: _11DesignPattern_ObserverDelegateTest 8 * MachineName: JIYF_PC 9 * CreateTime: 2017/5/23 20:56:50 10 * UpdatedTime: 2017/5/23 20:56:50 11 *****************************************************/ 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 using System.Text; 16 17 namespace _11DesignPattern_ObserverDelegateTest 18 { 19 /// <summary> 20 /// 具體的訂閱者類 21 /// </summary> 22 public class Observer 23 { 24 /// <summary> 25 /// 訂閱者名字 26 /// </summary> 27 private string m_Name; 28 public string Name 29 { 30 get { return m_Name; } 31 set { m_Name = value; } 32 } 33 34 /// <summary> 35 /// 訂閱者構造函數 36 /// </summary> 37 /// <param name="name">訂閱者名字</param> 38 public Observer(string name) 39 { 40 this.m_Name = name; 41 } 42 43 /// <summary> 44 /// 訂閱者接受函數 45 /// </summary> 46 /// <param name="blog"></param> 47 public void Receive(object obj) 48 { 49 Blog blog = obj as Blog; 50 if (blog != null) 51 { 52 Console.WriteLine("訂閱者:\"{0}\"觀察到了:{1}發布的一篇博客,標題為:{2},內容為:{3}", Name, blog.BlogName, blog.BlogTitle, blog.BlogInfo); 53 } 54 } 55 } 56 }
測試代碼
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace _11DesignPattern_ObserverDelegateTest 7 { 8 class Client 9 { 10 static void Main(string[] args) 11 { 12 Console.WriteLine("--全部訂閱者--"); 13 //創建一個JiYF的博客 14 Blog jiyfBlog = new Blog("JiYF笨小孩","醜小鴨","醜小鴨的故事"); 15 16 //創建訂閱者 17 Observer obsZhangsan = new Observer("張三"); 18 Observer obsLiSi = new Observer("李四"); 19 Observer obsWangwu = new Observer("王五"); 20 21 //添加對JiYF博客的訂閱者 22 jiyfBlog.AddObserver(new NotifyEventHandler(obsZhangsan.Receive)); 23 jiyfBlog.AddObserver(new NotifyEventHandler(obsLiSi.Receive)); 24 jiyfBlog.AddObserver(new NotifyEventHandler(obsWangwu.Receive)); 25 26 ////通知訂閱者 27 jiyfBlog.PublishBlog(); 28 29 Console.WriteLine("---移除訂閱者張三--"); 30 jiyfBlog.RemoteObserver(new NotifyEventHandler(obsZhangsan.Receive)); 31 jiyfBlog.PublishBlog(); 32 Console.ReadLine(); 33 } 34 } 35 }
運行結果:
源代碼工程文件下載
C#設計模式--觀察者模式(發布-訂閱模式)