当观察者希望观察不同的项目时实现观察者模式 [英] Implementing Observer pattern when observers wish to observe different items

查看:137
本文介绍了当观察者希望观察不同的项目时实现观察者模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面我试图为Observer模式编写一个sudo代码,当观察者希望观察不同的项目。

Below I have attempted to write a sudo code for the Observer pattern when observers wish to observe different items.

忽略语法错误。我想知道这是否是实现这一点的正确方法。

Ignore the syntax errors. I wish to know if this is the correct way to implement this. If not, please suggest better ways.

// Used by the subject for keeping a track of what items the observer wants to observe
typedef struct observerListStruct
{
    bool getTemperatureUpdate;
    bool getHumidityUpdate;
    bool getPressureUpdate;
    observer's-function pointer's address;
};

// Subject's class
class weatherData
{
    public:
        // Observers will call this function to register themselves. The function pointer will point to the function which will get called when updates are available.
        void registerObservers (observer obj, observer's-FunctionPointer)
        {
            // This observer's function returns which items to observe.
            char* f = obj.returnItemsToObserve ();
            if f[0] = `1`
                observerListStruct.getTemperatureUpdate = true;
        }

        void unregisterObservers (observer obj) {}

    private:
        vector <observerListStruct> observerList;
        float temperature;
        float humidity;
        float pressure;

        void notifyObservers ()          {}

        float getTemperature ()          {}
        float getHumidity ()                 {}
        float getPressure ()                 {}
} weatherDataObject;

// Base class for observers containing common functions
class observers
{
    char ItemsToObserve [3] = {1, 2, 3};

    // This observer's function returns which items to observe. Default - return all items
        virtual char* returnItemsToObserve ()
    {
        return ItemsToObserve;
    }
};

class observerDisplayElementCurrentConditions : public observers
{
    char ItemsToObserve [3] = {1, 2};

    char* returnItemsToObserve ()
    {
        return ItemsToObserve;
    }

    // this function will be used as a function pointer for getting updates
    void getUpdatesAndDisplayWeatherData (float, float) {}
};


推荐答案

更多的面向模式的解决方案可以是以下。你可以参数化WeatherObserver-Class来获取你想要的值。

A more pattern oriented solution (but without function pointers) could be the following. You could parametrize the WeatherObserver-Class to get only the values, you want.

#include <list>
#include <iostream>

class Observable;   //forward declaration

//Base class for all observers
class Observer {
    friend class Observable;    //allow access to observedSubject

protected:
    Observable *observedSubject;

public:
    virtual void update(){};
};


//Base class for all observables
class Observable {
private:
    std::list<Observer * const> m_registeredObservers;

public:
    ~Observable()
    {
        //delete the observers
        std::list<Observer * const>::iterator it = m_registeredObservers.begin();

        while (it != m_registeredObservers.end())
        {
            delete *it;
            it = m_registeredObservers.erase(it);
        }
    }

    void addObserver(Observer * const _pObserver)
    {
        _pObserver->observedSubject = this;
        m_registeredObservers.push_back(_pObserver);
    }

    void removeObserver(Observer * const _pObserver)
    {
        m_registeredObservers.remove(_pObserver);
        delete _pObserver;
    }

    void notifyObservers()
    {
        std::list<Observer * const>::iterator it = m_registeredObservers.begin();

        while (it != m_registeredObservers.end())
        {
            (*it)->update();
            it++;
        }
    }
};

//Concrete Observable
class WeatherData : public Observable {
private:
    float temperature;
    float humidity;
    float pressure;

public:
    WeatherData(): temperature(0), humidity(0), pressure(0)
    {};

    float getTemperature () const 
    {
        return temperature;
    }

    float getHumidity () const 
    {
        return humidity;
    }

    float getPressure () const 
    {
        return pressure;
    }

    void setTemperature(float _temperature)
    {
        if (temperature != _temperature)
        {
            temperature = _temperature;
            notifyObservers();
        }
    }

    void setHumidity(float _humidity)
    {
        if (humidity != _humidity)
        {
            humidity = _humidity;
            notifyObservers();
        }
    }

    void setPressure(float _pressure)
    {
        if (pressure != _pressure)
        {
            pressure = _pressure;
            notifyObservers();
        }
    }

};


//Concrete implementation of an weather observer
class WeatherObserver : public Observer 
{
    public:
        WeatherObserver():Observer(){};
        void update()
        {
            WeatherData* pWeatherPtr = static_cast<WeatherData*>(observedSubject);
            if (pWeatherPtr != 0)
            {
                float actHumidity = pWeatherPtr->getHumidity();
                float actPressure = pWeatherPtr->getPressure();
                float actTemperature = pWeatherPtr->getTemperature();

                //do something with the data
                std::cout << "WeatherObserver update" << std::endl;
                std::cout << "Temperature : " << actTemperature << std::endl;
                std::cout << "Humidity : " << actHumidity << std::endl;
                std::cout << "Pressure : " << actPressure << std::endl;
            }
        }
};

int main()
{
    WeatherData weatherData;
    Observer * pObserver = new WeatherObserver();
    weatherData.addObserver(pObserver);

    weatherData.setHumidity(100);
    weatherData.setTemperature(100);
}

这篇关于当观察者希望观察不同的项目时实现观察者模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆