C#高级特性及项目实战Day9
观察者模式(Observer Pattern)
简单介绍:
观察者模式(Observer Pattern)是设计模式中行为模式的一种,它解决了上述具有一对多依赖关系的对象的重用问题。此模式的参与者分为两大类,一类是被观察的目标,另一类是观察该目标的观察者们。正因为该模式是基于“一对多”的关系,所以该模式一般是应用于由一个目标对象和N个观察者对象组成(当然也可以扩展为有多个目标对象,但我们现在只讨论前者)的场合。当目标对象的状态发生改变或做出某种行为时,正在观察该目标对象的观察者们将自动地、连锁地作出相应的响应行为。
模式中具有的角色
- 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
- 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
- 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
- 具体观察者(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 /// <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 }

浙公网安备 33010602011771号