Head First 设计模式详解之二:观察者模式

什么是观察者模式

对象之间存在一对多的关系,当一个对象状态发生改变时,会通知其他依赖的对象,并使他们自动更新。


举个例子

我们有一个气象站,并拥有多个种类展示板。当气象站检测到的气象数据发生改变时,展示板也进行相应的改变。

我们可以维护一个动态数组,将所有的依赖对象放到里面,状态更新函数update由依赖的类实现。当我们状态发生改变时,只要一一调用数组中的对象的update函数。为此,被依赖对象需要继承一个Subject接口,而依赖对象需要继承一个Observer接口。

我们创建一个WeatherData类,当WeatherData发生改变时,我们通知多种Display类来作出更新。

#include <iostream>
#include <vector>
#include <algorithm>
#include <typeinfo>
using namespace std;
class Observable;
// 观察者接口
class Observer{
public:
    virtual void update(Observable*, void*) = 0;
};
// 被观察者接口
class Observable{
public:
    vector<Observer*> ObserverArray;
    // 注册观察者
    virtual void RegisterObserver(Observer* Ob){ObserverArray.push_back(Ob);}
    // 移除观察者
    virtual void RemoveObserver(Observer* Ob){ObserverArray.erase(find(ObserverArray.begin(),ObserverArray.end(),Ob));}
    // 状态改变,通知所有观察者
    virtual void NotifyObserver(){
        if(Changeflag){
            vector<Observer*>::iterator it_begin = ObserverArray.begin();
            vector<Observer*>::iterator it_end = ObserverArray.end();
            for(; it_begin != it_end; it_begin++){
                (*it_begin) -> update(this, (void*)this);
            }
            Changeflag = false;
        }
    }
    virtual void setChange(){
        Changeflag = true;
    }
private:
    bool Changeflag = false;
};

class WeatherData:public Observable{
private:
    int temperature;
    int pressure;
public:
    WeatherData(int t, int p) :
        temperature(t),
        pressure(p)
    {}
    void ChangeStatus(){
        setChange();
        NotifyObserver();
    }
    int GetTemperature(){ return temperature; }
    int GetPressure(){ return pressure; }
};

class Display:public Observer{
public:
    Display(Observable* Ob): m_Ob(Ob){
        Ob->RegisterObserver(this);
    }
    void show(){
        cout << "temperature is " << temperature << endl;
        cout << "pressure is " << pressure << endl;
    }
    void update(Observable* ob, void* source){
        // 判断发出通知的是哪个被观察者
        if(typeid(*ob) == typeid(WeatherData)){
            
            temperature = ((WeatherData*)source) -> GetTemperature();
            pressure = ((WeatherData*)source) -> GetPressure();
            show();
        }
    }
private:
    Observable* m_Ob;
    int temperature = 0;
    int pressure = 0;
};

int main(){
    WeatherData weather(1,2);
    Display myDisplay(&weather);
    myDisplay.show();
    weather.ChangeStatus();
}

输出结果为:

temperature is 0
pressure is 0
temperature is 1
pressure is 2

当我们的WeatherData发生状态改变时,成功通知到了其中的依赖对象。

使用观察者模式,我们可以动态地管理监听的对象,状态更新的代码也由更新方提供,被监听方不需要去关心监听方的任何实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值