zoukankan      html  css  js  c++  java
  • 设计模式->观察者模式

    观察者模式能非常大的减少模块之前的耦合。具体的观察者模式,客官们可以去看《设计模式》或者《Head first设计模式》等之类的书。


    在java中,java.util库中封装了观察者模式。在C++中并没有这玩意。以下就是为了封装一个C++的观察者模式而写。


    观察者模式中,对于主题(subject)和观察者(observer)的接口可以是抽象出来的,而这些接口差不多都是通用的,然后要用时只要去继承这些接口,完成相应的处理即可。java中的实现也是一样的道理。


    观察者,很明显是要去观察一样东西。但是,对于不同的具体实现,要观 察的东西并不同啊!比如要实现一个天气预报的,我要观察温度、湿度等。要实现一个消息的显示程序,那么我要观察的就是消息了。对于不同的实现,有些要观察 的不只一个变量,有的只有一个变量。在C++中,可以使用变长的参数表,但是,这样的实现会带来很多问题,比如类型安全等。还有什么办法可以处理不定个变 量呢?目前,我能想到的就只有用类、结构体去封装了。那么要适应不同的类呢?那就要用到模板了。

    以下是初步的实现。

    subject类的设计如下:

    template <typename TContent>
    class Subject
    {
    public:
        typedef TContent Content;     ///< 观察的内容类型
        typedef Observer<Content> AbstractObserver;     ///< 观察者的抽象类型

        void registerObserver(AbstractObserver *obs);

        void unregisterObserver(AbstractObserver *obs);

        void notifyObservers(TContent cnt);
    private:
        typedef std::list<AbstractObserver*> ObserverList;
        typedef typename ObserverList::iterator ObserverListIterator;
        ObserverList _observers;

    };

    这里将要观察的内容设为TContent,如果要观察多个值的对象,可以封装一个struct,然后做为模板参数传进来。


    observer类的设计如下:

    template <typename TContent>
    class Observer
    {
    public:
        typedef TContent Content;

        /**
         * @brief update 当有新内容时会被调用
         *
         * 子类化此类,重写这个函数
         * @param cnt 将的内容通过这个参数传入
         */
        virtual void update(TContent cnt) = 0;

    private:
    };

    具体的实现代码,可以参见我的github。


    这样封装后,就可以很方便使用了。以下是我使用的一个例子。

    class ConcreteSubject : public Subject<int>
    {
    public:
        ConcreteSubject() : times(0)
        {

        }

        void run()
        {
            this->notifyObservers(times);
            ++times;
        }

    private:
        int times;
    };

    class ConcreteObserver : public Observer<int>
    {
    public:
        virtual void update(int cnt)
        {
            cout << cnt << endl;
        }
    };

    丫丫吧,好店大全,畅销产品推荐 http://www.yayaba.cn

  • 相关阅读:
    【总结】进程和线程的区别
    为什么要求数据链路层帧的长度必须限制在一定范围内?
    常用正交表
    用正交表设计测试用例
    测试中的杀虫剂困境
    作品集-1:淘宝支付宝登陆框
    # 36氪开放日 • 杭州 • 11月10日 # 谈谈参会感受
    《在你身边,为你设计》读后感
    抱怨的背后
    更快的方式实现PHP数组去重
  • 原文地址:https://www.cnblogs.com/zycblog/p/3679093.html
Copyright © 2011-2022 走看看