0%

观察者模式CSharp实现

0.C#设计模式–简单工厂模式

1.C#设计模式–工厂方法模式

2.C#设计模式–抽象工厂模式

3.C#设计模式–单例模式

4.C#设计模式–建造者模式

5.C#设计模式–原型模式

6.C#设计模式–设配器模式

7.C#设计模式–装饰器模式

8.C#设计模式–代理模式

9.C#设计模式–外观模式

10.C#设计模式–桥接模式

简单介绍:

  观察者模式(Observer Pattern)是设计模式中行为模式的一种,它解决了上述具有一对多依赖关系的对象的重用问题。此模式的参与者分为两大类,一类是被观察的目标,另一类是观察该目标的观察者们。正因为该模式是基于“一对多”的关系,所以该模式一般是应用于由一个目标对象和N个观察者对象组成(当然也可以扩展为有多个目标对象,但我们现在只讨论前者)的场合。当目标对象的状态发生改变或做出某种行为时,正在观察该目标对象的观察者们将自动地、连锁地作出相应的响应行为。

模式中具有的角色

  1. 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
  2. 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
  3. 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
  4. 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

举例子:博客的例子就是一个观察者模式,比如你关注一些作者的博客,当作者有博客发布时候,你就会收到一条该作者发布的博客的消息。

抽象主题:Blog 博客

具体主题:MyBlog   的博客

抽象观察者:IObserver  

具体的观察者:Observer

观察者模式类图:

观察者模式C#代码举例

订阅博客抽象类

复制代码

1 /*****************************************************
2 * ProjectName: _11DesignPattern_Observer
3 * Description:
4 * ClassName: Blog
5 * CLRVersion: 4.0.30319.18408
6 * Author: JiYF
7 * 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 ///


20 /// 订阅博客抽象类 21 ///

22 public abstract class Blog 23 { 24 ///
25 /// 保存订阅者列表 26 ///

27 private List observers = new List(); 28
29 ///
30 /// 博主名 31 ///

32 public string BlogName { get; set; } 33
34 ///
35 /// 博客标题 36 ///

37 public string BlogTitle { get; set; } 38
39 ///
40 /// 博客信息 41 ///

42 public string BlogInfo { get; set; } 43
44 ///
45 /// 博客构造函数 46 ///

47 /// 博客标题
48 /// 博客信息
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 ///
57 /// 添加一个订阅者 58 ///

59 /// 具体的订阅者对象
60 public void AddObserver(IObserver observer) 61 { 62 if (observers.Contains(observer)) 63 { 64 return; 65 } 66 observers.Add(observer); 67 } 68
69 ///
70 /// 删除一个订阅者 71 ///

72 /// 具体的订阅者对象
73 public void RemoveObserver(IObserver observer) 74 { 75 if (observers.Contains(observer)) 76 { 77 observers.Remove(observer); 78 } 79 } 80
81 ///
82 /// 发布博客通知 83 ///

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 ///


21 /// 具体的订阅博客类 22 ///

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 ///


20 /// 订阅者接口 21 ///

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 ///


20 /// 具体的订阅者类 21 ///

22 public class Observer :IObserver 23 { 24 ///
25 /// 订阅者名字 26 ///

27 private string m_Name; 28 public string Name 29 { 30 get { return m_Name; } 31 set { m_Name = value; } 32 } 33
34 ///
35 /// 订阅者构造函数 36 ///

37 /// 订阅者名字
38 public Observer(string name) 39 { 40 this.m_Name = name; 41 } 42
43 ///
44 /// 订阅者接受函数 45 ///

46 ///
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 ///


20 /// 委托充当订阅者接口类 21 ///

22 ///
23 public delegate void NotifyEventHandler(object sender); 24
25 ///
26 /// 订阅博客基类 27 ///

28 public class Blog 29 { 30 public NotifyEventHandler NotifyEvent; 31 ///
32 /// 博主名 33 ///

34 public string BlogName { get; set; } 35
36 ///
37 /// 博客标题 38 ///

39 public string BlogTitle { get; set; } 40
41 ///
42 /// 博客信息 43 ///

44 public string BlogInfo { get; set; } 45
46 ///
47 /// 博客构造函数 48 ///

49 /// 博客标题
50 /// 博客信息
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 ///
59 /// 绑定订阅事件 60 ///

61 /// 订阅者
62 public void AddObserver(NotifyEventHandler observer) 63 { 64 NotifyEvent += observer; 65 } 66
67 ///
68 /// 取消绑定订阅 69 ///

70 ///
71 public void RemoteObserver(NotifyEventHandler observer) 72 { 73 NotifyEvent -= observer; 74 } 75
76 ///
77 /// 发布博客通知 78 ///

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 ///


20 /// 具体的订阅博客类 21 ///

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 ///


20 /// 具体的订阅者类 21 ///

22 public class Observer 23 { 24 ///
25 /// 订阅者名字 26 ///

27 private string m_Name; 28 public string Name 29 { 30 get { return m_Name; } 31 set { m_Name = value; } 32 } 33
34 ///
35 /// 订阅者构造函数 36 ///

37 /// 订阅者名字
38 public Observer(string name) 39 { 40 this.m_Name = name; 41 } 42
43 ///
44 /// 订阅者接受函数 45 ///

46 ///
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 }

复制代码

运行结果:

 

源代码工程文件下载