• 设计模式(二):观察者模式


      在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。

      通俗点来说,就是一个主题类(subject)在状态发生改变时,通过观察者(observer)提供的方法,来更新观察者的状态。首先观察者需要到主题类中注册。

    附带维基百科的代码:

    python:相对简洁

    class AbstractSubject(object):
        def register(self, listener):
            raise NotImplementedError("Must subclass me")
     
        def unregister(self, listener):
            raise NotImplementedError("Must subclass me")
     
        def notify_listeners(self, event):
            raise NotImplementedError("Must subclass me")
     
    class Listener(object):
        def __init__(self, name, subject):
            self.name = name
            subject.register(self)
     
        def notify(self, event):
            print self.name, "received event", event
     
    class Subject(AbstractSubject):
        def __init__(self):
            self.listeners = []
            self.data = None
     
        def getUserAction(self):
            self.data = raw_input('Enter something to do:')
            return self.data
     
        # Implement abstract Class AbstractSubject
     
        def register(self, listener):
            self.listeners.append(listener)
     
        def unregister(self, listener):
            self.listeners.remove(listener)
     
        def notify_listeners(self, event):
            for listener in self.listeners:
                listener.notify(event)
     
     
    if __name__=="__main__":
        # make a subject object to spy on
        subject = Subject()
     
        # register two listeners to monitor it.
        listenerA = Listener("<listener A>", subject)
        listenerB = Listener("<listener B>", subject)
     
        # simulated event
        subject.notify_listeners ("<event 1>")
        # outputs:
        #     <listener A> received event <event 1>
        #     <listener B> received event <event 1>
     
        action = subject.getUserAction()
        subject.notify_listeners(action)
        #Enter something to do:hello
        # outputs:
        #     <listener A> received event hello
        #     <listener B> received event hello

    C++代码,需要多理解:

    #include <list>
    #include <vector>
    #include <algorithm>
    #include <iostream>
    using namespace std;
     
    // The Abstract Observer
    class ObserverBoardInterface
    {
    public:
        virtual void update(float a,float b,float c) = 0;
    };
     
    // Abstract Interface for Displays
    class DisplayBoardInterface
    {
    public:
        virtual void show() = 0;
    };
     
    // The Abstract Subject
    class WeatherDataInterface
    {
    public:
        virtual void registerob(ObserverBoardInterface* ob) = 0;
        virtual void removeob(ObserverBoardInterface* ob) = 0;
        virtual void notifyOb() = 0;
    };
     
    // The Concrete Subject
    class ParaWeatherData: public WeatherDataInterface
    {
    public:
        void SensorDataChange(float a,float b,float c)
        {
            m_humidity = a;
            m_temperature = b;
            m_pressure = c;
            notifyOb();
        }
     
        void registerob(ObserverBoardInterface* ob)
        {
            m_obs.push_back(ob);
        }
     
        void removeob(ObserverBoardInterface* ob)
        {
            m_obs.remove(ob);
        }
    protected:
        void notifyOb()
        {
            list<ObserverBoardInterface*>::iterator pos = m_obs.begin();
            while (pos != m_obs.end())
            {
                ((ObserverBoardInterface* )(*pos))->update(m_humidity,m_temperature,m_pressure);
                (dynamic_cast<DisplayBoardInterface*>(*pos))->show();
                ++pos;
            }
        }
     
    private:
        float        m_humidity;
        float        m_temperature;
        float        m_pressure;
        list<ObserverBoardInterface* > m_obs;
    };
     
    // A Concrete Observer
    class CurrentConditionBoard : public ObserverBoardInterface, public DisplayBoardInterface
    {
    public:
        CurrentConditionBoard(WeatherDataInterface& a):m_data(a)
        {
            m_data.registerob(this);
        }
        void show()
        {
            cout<<"_____CurrentConditionBoard_____"<<endl;
            cout<<"humidity: "<<m_h<<endl;
            cout<<"temperature: "<<m_t<<endl;
            cout<<"pressure: "<<m_p<<endl;
            cout<<"_______________________________"<<endl;
        }
     
        void update(float h, float t, float p)
        {
            m_h = h;
            m_t = t;
            m_p = p;
        }
     
    private:
        float m_h;
        float m_t;
        float m_p;
        WeatherDataInterface& m_data;
    };
     
    // A Concrete Observer
    class StatisticBoard : public ObserverBoardInterface, public DisplayBoardInterface
    {
    public:
        StatisticBoard(WeatherDataInterface& a):m_maxt(-1000),m_mint(1000),m_avet(0),m_count(0),m_data(a)
        {
            m_data.registerob(this);
        }
     
        void show()
        {
            cout<<"________StatisticBoard_________"<<endl;
            cout<<"lowest  temperature: "<<m_mint<<endl;
            cout<<"highest temperature: "<<m_maxt<<endl;
            cout<<"average temperature: "<<m_avet<<endl;
            cout<<"_______________________________"<<endl;
        }
     
        void update(float h, float t, float p)
        {
            ++m_count;
            if (t>m_maxt)
            {
                m_maxt = t;
            }
            if (t<m_mint)
            {
                m_mint = t;
            }
            m_avet = (m_avet * (m_count-1) + t)/m_count;
        }
     
    private:
        float m_maxt;
        float  m_mint;
        float m_avet;
        int m_count;
        WeatherDataInterface& m_data;
    };
     
     
    int main(int argc, char *argv[])
    {
     
        ParaWeatherData * wdata = new ParaWeatherData;
        CurrentConditionBoard* currentB = new CurrentConditionBoard(*wdata);
        StatisticBoard* statisticB = new StatisticBoard(*wdata);
     
        wdata->SensorDataChange(10.2, 28.2, 1001);
        wdata->SensorDataChange(12, 30.12, 1003);
        wdata->SensorDataChange(10.2, 26, 806);
        wdata->SensorDataChange(10.3, 35.9, 900);
     
        wdata->removeob(currentB);
     
        wdata->SensorDataChange(100, 40, 1900);  
     
        delete statisticB;
        delete currentB;
        delete wdata;
     
        return 0;
    }
  • 相关阅读:
    bzoj 3111 蚂蚁 动态规划
    bzoj3011 可并堆
    bzoj2693 莫比乌斯反演
    bzoj 2671 莫比乌斯反演
    bzoj2194 快速傅立叶之二 FFT
    bzoj1396&&2865 识别子串 后缀自动机+线段树
    安卓开发中使用ZXing生成解析二维码
    使用tencent协议发起临时会话
    使用zxing编写的二维码生成解析工具:QRCoder
    使用JavaScript获取浏览器Chrome版本信息
  • 原文地址:https://www.cnblogs.com/bracken/p/2987954.html
Copyright © 2020-2023  润新知