zl程序教程

您现在的位置是:首页 >  后端

当前栏目

观察者模式

模式 观察者
2023-09-14 09:00:57 时间

在典型的网络通信处理软件里面(比如QQ),我们常常需要在接收到一条消息的时候,对消息进行解码、将消息写入日志文件(以便后面排查问题)、将消息写到某个界面上(如下面代码所示)。也就是说,我们一共需要通知三个不同的对象,我们收到了一条消息。这代码看着总觉得有点多余,为什么要连续写三次差不了多少的函数调用呢?所以观察者模式就是用来解决这个问题的,应用观察者模式,我们可以实现对多个观察者的通知(其实就是调用观察者相应的函数来处理消息),在下面代码里有Decoder、Logger、UI三个观察者。

复制代码
class MessageProcesser

 /// summary 

 /// 这里模式收到网络消息的处理函数

 /// /summary 

 /// param name="Message" /param 

 public void ProcessMsg(String Message) {

 Docoder.Decode(Message); //对消息进行解析

 Logger.Log(Message); //将消息写入日志文件

 UI.Notice(Message); //在界面上显示收到的消息

 }
复制代码

1、首先,我们可以做的第一件事情就是将不同的函数抽象成一个接口。

public interface IUpdatableObject

 string Data { get; }

 void Update(String newData);

 }

2、我们也可以将目标对象(也就是上面的MessageProcesser)抽象一下,这样的话,经过对Docoder.Decode()、Loger.Log()、UI.Notice()的抽象,我们的MessageProcesser已经只需要依赖一个抽象的IUpdateObject。我们想要达到通知多个对象的方法很简单,比较容易想到的方法就是在MessageProcesser类里面保存一个List IUpdateObject 类型的链表,然后通过依次调用链表中的Update()函数就可以实现通知多个对象(Docoder、Loger、UI.)的效果了。

复制代码
public class MessageProcesser

 IUpdatableObject[] objs;

 public MessageProcesser()

 objs = new IUpdatableObject[3];

 public IUpdatableObject this[int index]

 set { objs[index] = value; }

 public string Data { get; private set; }

 /// summary 

 /// 这里模式收到网络消息的处理函数

 /// /summary 

 /// param name="Message" /param 

 public void ProcessMsg(String Message)

 this.Data = Message;

 foreach (var item in objs)

 item.Update(Message);

 }
复制代码

实现了接口IUpdateobject后的MDecoder、Logger、UI类

复制代码
/// summary 

 /// 模拟解码类

 /// /summary 

 public class MDecoder : IUpdatableObject

 string data;

 public string Data

 get { return this.data; }

 public void Update(string newData)

 data = newData;

 /// summary 

 /// 模拟日志类

 /// /summary 

 public class Logger : IUpdatableObject

 string data;

 public string Data

 get { return this.data; }


复制代码
/// summary 

 ///ProcessMsg 的测试

 /// /summary 

 [TestMethod()]

 public void ProcessMsgTest()

 MessageProcesser target = new MessageProcesser();

 IUpdatableObject MDecoder = new MDecoder();

 IUpdatableObject Logger = new Logger();

 IUpdatableObject UI = new UI();

 target[0] = MDecoder;

 target[1] = Logger;

 target[2] = UI;

 string Message = "Hello World"; 

 target.ProcessMsg(Message); //通知多个对象收到消息了

 Assert.AreEqual(Message, MDecoder.Data);//判断接口内的数据是否与收到的一致,

 Assert.AreEqual(Message, Logger.Data); //如果一致,则说明消息已经通知到各个对象了

 Assert.AreEqual(Message, UI.Data);

 }
复制代码

测试的结果是通过,说明我们已经完成了对同时对多个对象的通知。从以上代码,我们也可看出其实经典的观察者模式就是将观察者抽象成接口,然后在目标对象(被观察者)内保存对观察者接口的引用,这样在目标对象状态发生变化的时候,就可以通过遍历所有的观察者,实现通知所有人的效果。



作者:kissazi2 
出处:http://www.cnblogs.com/kissazi2/ 
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/kissazi2/p/3286753.html


我学会了,观察者模式 观察者模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。