观察者模式

在典型的网络通信处理软件里面(比如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; }
        }

        public void Update(string newData)
        {
            data = newData;
        }
    }
    /// <summary>
    /// 模拟界面类
    /// </summary>
    public class UI : IUpdatableObject
    {

        string data;
        public string Data
        {
            get { return this.data; }
        }

        public void Update(string newData)
        {
            data = newData;
        }
    }

3、接下来,我们就可以看看观察者模式实现对多个观察者通知的效果

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

时间: 2024-09-01 04:56:09

观察者模式的相关文章

设计模式之观察者模式(关于OC中的KVO\KVC\NSNotification)

学习了这么久的设计模式方面的知识,最大的感触就是,设计模式不能脱离语言特性.近段时间所看的两本书籍,<大话设计模式>里面的代码是C#写的,有一些设计模式实现起来也是采用了C#的语言特性(C#的API,抽象类,在OC中是没有抽象类.没有多继承关系),<设计模式之禅>里面的代码是JAVA写的,与OC差距也是比较大. 但是我想,这些都不是问题,学习设计模式主要学习的是其中的思想,并将之改造成自己所熟悉语言的模式,大同小异.所需要注意的是,在学习的过程中,将之与语言结合起来,多思考.多实践

C#之观察者模式

观察者模式(Observer)完美的将观察者和被观察的对象分离开.举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上.面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面.一个对象只做一件事情,并且将他做好.观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性. 观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象.在刚才的例子中,业务数据是被观察对象,用户界

设计模式-观察者模式

观察者模式分析 观察者模式又叫做发布-订阅(Publish/Subscribe)模式. 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 特点: 观察者模式的通知者可以有任意数目的依赖它的Observer,一旦通知者的状态改变,所有的Observer都可以得到通知.通知者发出通知时并不需要知道谁是它的观察者,也就是说,具体观察者是谁,它根本不需要知道. 总得来讲,观察者模式所做的工作其实就是

JavaScript设计模式之观察者模式

设计模式(Design Pattern)对于软件开发来说其重要性不言而喻,代码可复用.可维护.可扩展一直都是软件工程中的追求!对于我一个学javascript的人来说,理解设计模式似乎有些困难,对仅切图.做少量交互效果的FE甚至可能不会用到,但是当你开始使用Angular/Backbone等框架的时候,就无法避免设计模式.MVC/MVVM这些东西了(反正我是伤脑筋). 我学设计模式是刚开始接触编程大概三个月的时候,看一本书<大话设计模式>,里面用C#语言来写,我很无语,因为强类型的编程语言对于

php设计模式之观察者模式

观察者模式: 观察者模式定义对象的 一对多 依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新! 在观察者模式中,会改变的是主题的状态以及观察者的数目.用这个模式,你可以改变依赖于主题状态的对象,却不必改变主题.--找出程序中会变化的方面,然后将其和固定不变的方面相分离! 主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者.这样可以让两者之间运作正常,又同时具有松耦合的优点! --针对接口编程,不针对实现编程! 观察者模式利用"组合&q

php设计模式 Observer(观察者模式)

复制代码 代码如下: <?php /** * 观察者模式 * * 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新 * 能够便利地创建查看目标对象状态的对象,并且提供与核心对象非耦合的指定功能 * 插件系统 */ class Observerable { private $_observers = array(); public function registerObserver($observer) { $this->_observer

.NET中的设计模式五:观察者模式

设计 观察者模式(Observer)完美的将观察者和被观察的对象分离开.举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上.面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面.一个对象只做一件事情,并且将他做好.观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性. 观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象.在刚才的例子中,业务数据是被观察对象,

设计模式之观察者模式(Observer Pattern)(一)

server|设计 我们通常在同一时间将我们的数据表示为各种不同的形式,比如列表.图形等等. 我们也同样希望当数据改变时,将这个更新信息很方便的通知所有依赖于它的各个对象. 例如:我们可以使用图形.表格或者列表框显示股票的价格,当股票的价格发生改变时,我们期望同时很方便的更改其它部分. 在这种情况下我们就可以使用Observer模式.我们可以很容易的利用Observer模式使我们的程序可以很方便的解决上面的问题. 结构图: 观察者模式假定保存数据的对象和显示数据的对象是分开的,负责显示数据的对象

观察者模式(Observer Pattern) 详解

观察者模式(Observer Pattern): 定义了对象之间的一对多的依赖, 这样一来, 当一个对象改变状态时, 它的所有依赖者都会收到通知并自动更新. 使用方法: 1. 首先新建主题(subject)接口, 负责注册(register)\删除(remove)\通知(notify)观察者; 观察者(observer)接口, 负责更新(update)数据; 主题(subject)接口: 注册观察者(registerObserver), 删除观察者(removeObserver), 通知观察者(

观察者模式(Observer Pattern) Java内置使用方法

Java内置的观察者模式, 是通过继承父类, 实现观察者模式的几个主要函数: Observerable(可被观察的): 是一个父类(class),addObserver(), 添加观察者; deleteObserver(), 删除观察者; notifyObservers(), 通知观察者;setChanged(), 确认更改; Observer(观察者): 是一个接口(interface), update(), 更新观察者数据; setChanged()->notifyObservers(),