C#设计模式(17)——观察者模式(Observer Pattern)

  在现实生活中,处处可见观察者模式,例如,微信中的订阅号,订阅博客和QQ微博中关注好友,这些都属于观察者模式的应用。在这一章将分享我对观察者模式的理解,废话不多说了,直接进入今天的主题。

二、 观察者模式的介绍 2.1 观察者模式的定义

  从生活中的例子可以看出,只要对订阅号进行关注的客户端,如果订阅号有什么更新,就会直接推送给订阅了的用户。从中,我们就可以得出观察者模式的定义。

  观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己的行为。

2.2 观察者模式的结构

  从上面观察者模式的定义和生活中的例子,很容易知道,观察者模式中首先会存在两个对象,一个是观察者对象,另一个就是主题对象,然而,根据面向接口编程的原则,则自然就有抽象主题角色和抽象观察者角色。理清楚了观察者模式中涉及的角色后,接下来就要理清他们之间的关联了,要想主题对象状态发生改变时,能通知到所有观察者角色,则自然主题角色必须所有观察者的引用,这样才能在自己状态改变时,通知到所有观察者。有了上面的分析,下面观察者的结构图也就很容易理解了。具体结构图如下所示:

C#设计模式(17)——观察者模式(Observer Pattern)

                                  图 观察者模式结构图

  可以看出,在观察者模式的结构图有以下角色:

抽象主题角色(Subject):抽象主题把所有观察者对象的引用保存在一个列表中,并提供增加和删除观察者对象的操作,抽象主题角色又叫做抽象被观察者角色,一般由抽象类或接口实现。

抽象观察者角色(Observer):为所有具体观察者定义一个接口,在得到主题通知时更新自己,一般由抽象类或接口实现。

具体主题角色(ConcreteSubject):实现抽象主题接口,具体主题角色又叫做具体被观察者角色。

具体观察者角色(ConcreteObserver):实现抽象观察者角色所要求的接口,以便使自身状态与主题的状态相协调。

2.3 观察者模式的实现

  下面以微信订阅号的例子来说明观察者模式的实现。现在要实现监控腾讯游戏订阅号的状态的变化。这里一开始不采用观察者模式来实现,而通过一步步重构的方式,最终重构为观察者模式。因为一开始拿到需求,自然想到有两个类,一个是腾讯游戏订阅号类,另一个是订阅者类。订阅号类中必须引用一个订阅者对象,这样才能在订阅号状态改变时,调用这个订阅者对象的方法来通知到订阅者对象。有了这个分析,自然实现的代码如下所示:

1 // 腾讯游戏订阅号类 2 public class TenxunGame 3 { 4 // 订阅者对象 5 public Subscriber Subscriber {get;set;} 6 7 public String Symbol {get; set;} 8 9 public string Info {get ;set;} 10 11 public void Update() 12 { 13 if (Subscriber != null) 14 { 15 // 调用订阅者对象来通知订阅者 16 Subscriber.ReceiveAndPrintData(this); 17 } 18 } 19 20 } 21 22 // 订阅者类 23 public class Subscriber 24 { 25 public string Name { get; set; } 26 public Subscriber(string name) 27 { 28 this.Name = name; 29 } 30 31 public void ReceiveAndPrintData(TenxunGame txGame) 32 { 33 Console.WriteLine("Notified {0} of {1}\'s" + " Info is: {2}", Name, txGame.Symbol, txGame.Info); 34 } 35 } 36 37 // 客户端测试 38 class Program 39 { 40 static void Main(string[] args) 41 { 42 // 实例化订阅者和订阅号对象 43 Subscriber LearningHardSub = new Subscriber("LearningHard"); 44 TenxunGame txGame = new TenxunGame(); 45 46 txGame.Subscriber = LearningHardSub; 47 txGame.Symbol = "TenXun Game"; 48 txGame.Info = "Have a new game published ...."; 49 50 txGame.Update(); 51 52 Console.ReadLine(); 53 } 54 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwpggs.html