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

  • 相关阅读:
    call()与apply()的作用与区别
    Tomcat8/9的catalina.out中文乱码问题解决
    怎样查看Jenkins的版本
    每日日报2020.8.18
    528. Random Pick with Weight
    875. Koko Eating Bananas
    721. Accounts Merge
    515. Find Largest Value in Each Tree Row
    286. Walls and Gates (Solution 1)
    408. Valid Word Abbreviation
  • 原文地址:https://www.cnblogs.com/zycblog/p/3679093.html
Copyright © 2011-2022 走看看