C++设计模式--观察者模式详解(head first 设计模式C++实现)

观察者模式

  1. 观察者模式可以帮观察者知悉主题的现况。观察者对象甚至在运行的时候可决定是否要继续被主题通知。
  2. 观察者模式一般被运用于一个需要通知的主题对象,对应多个需要接收消息的观察者对象。可以动态的添加和删除观察者对象。
  3. 观察者模式,观察者和主题之间是松耦合的,体现的设计原则:
  • 为了实现交互对象之间的松耦合设计而努力。
  • 针对接口编程,不针对实现编程
  • 多用组合,少用继承
  1. 观察者模式定义了对象之间一对多的关系。
  2. 主题用一个共同的接口来更新观察者
  3. 可观察者不知道观察者的细节,只知道管擦在实现了观察者接口

例子

在这里插入图片描述
在这里插入图片描述


//展示方法抽象类
class DisplayElement{
    public:
        virtual void display() const=0;
        virtual ~DisplayElement(){}
};
//观察者抽象类
class Observer{
    public:
        virtual void update(const float& ,const float& ,const float&)=0;
        virtual ~Observer(){}

};

class Subject{
    public:
        virtual bool registerObserver(Observer*)=0;
        virtual bool removeObserver(Observer*)=0;
        virtual void notifyObserver()=0;
        virtual ~Subject(){}
};

class WeatherData:public Subject{
    private:
        vector<Observer*> observers;
        float temp=0,humidity=0,pressure=0;
         
    public:
        WeatherData(){}
        ~WeatherData(){
            for(Observer*& it:observers){
                if(it!=nullptr){
                    delete it;
                    it=nullptr;
                }
            }
        }

        virtual bool registerObserver( Observer* newobserver){
            if(newobserver==nullptr){
                return false;
            }
            observers.push_back(newobserver);
            return true;
        }

        virtual bool removeObserver(Observer* oldobserver){
            int i=-1; 
            for(Observer*& it:observers){
                ++i;
                if(it==oldobserver){
                    observers.erase(observers.begin()+i);
                    return true;
                }
            }

            return false;
        }

    private:
        virtual void notifyObserver(){
            for(const auto& it:observers){
                it->update(temp,humidity,pressure);
            }
        }

        void measurementsChanged(){
            notifyObserver();
        }
    public:
        void getTemp(const float& m_temp){
            temp=m_temp;
            measurementsChanged();
        } 
        void getHumidity(const float& m_humidity){
            humidity=m_humidity;
            measurementsChanged();
        } 
        void getPressure(const float& m_pressure){
            pressure=m_pressure;
            measurementsChanged();
        }

        void setData(const float& m_temp,const float& m_hum,const float& pre){
            temp=m_temp;
            humidity=m_hum;
            pressure=pre;
            measurementsChanged();
        } 


};

class CurrentConditionsDisplay:public Observer,public DisplayElement{
    private:
        float temp,humidity,pressure;
        Subject* weather=nullptr;

    public:
        CurrentConditionsDisplay(Subject* m_weather):weather(m_weather){

        }
        ~CurrentConditionsDisplay(){
            if(weather){
                delete weather;
                weather=nullptr;
            }
        }

        virtual void update(const float& m_temp,const float& m_humidity,const float& m_pressure){
                temp=m_temp;
                humidity=m_humidity;
                pressure=m_pressure; 
                display();
        }
        virtual void display()  const{
            cout<<"CurrentConditionsDisplay:"<<endl;
            cout<<" temp="<<temp<<" humidity="<<humidity<<" pressure"<<pressure<<endl<<endl;
        }  

        void giveupObserver(){
            weather->removeObserver(this);
        }

        void startObserver(){
            weather->registerObserver(this);
        }


}; 


class ForecasDisplay:public Observer,public DisplayElement{
    private:
        float temp,humidity,pressure;
        Subject* weather=nullptr;

    public:
        ForecasDisplay(Subject* m_weather):weather(m_weather){

        }
        ~ForecasDisplay(){
            if(weather){
                delete weather;
                weather=nullptr;
            }
        }

        virtual void update(const float& m_temp,const float& m_humidity,const float& m_pressure){
                temp=m_temp;
                humidity=m_humidity;
                pressure=m_pressure; 
                display();
        }
        virtual void display()  const{
            cout<<"ForecasDisplay:"<<endl;
            cout<<" temp="<<temp<<" humidity="<<humidity<<" pressure"<<pressure<<endl<<endl;
        }  

        void giveupObserver(){
            weather->removeObserver(this);
        }

        void startObserver(){
            weather->registerObserver(this);
        }


}; 




int main(){
    WeatherData* weather = new WeatherData; //对象

    CurrentConditionsDisplay* display1 = new CurrentConditionsDisplay(weather);
    ForecasDisplay* display2 = new ForecasDisplay(weather);
    weather->registerObserver(display1);
    
    //weather->registerObserver(display2);  主题主动添加观察者
    display2->startObserver();  //观察者主动启动主题开始观察


    //更新数据
    weather->setData(12,34,56);
    //display1放弃观察
    display1->giveupObserver();
    
     
    weather->setData(45,4,6);


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值