行为型模式-观察者模式

发布时间 2023-11-10 16:18:35作者: Qt小罗

1 什么是观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都会得到通知并自动更新。

观察者模式包括两种类型的对象:主题(Subject)和观察者(Observer)。主题是被观察的对象,它维护一组依赖于它的观察者对象,并提供方法来注册、删除和通知观察者。观察者是依赖于主题的对象,它定义了一个更新接口,以使得主题在状态变化时能够通知到它们。

2 举个例子

下面以一个简单的天气预报系统为例来说明观察者模式的应用。假设我们有一个气象站系统,它可以不断地获取实时的天气信息,并将这些信息推送给所有订阅了天气预报的观察者。

首先,我们定义观察者接口 Observer,其中包含了一个更新天气信息的方法:

class Observer {
public:
    virtual void update(string weatherInfo) = 0;
    virtual ~Observer() {}
};

然后,我们创建具体的观察者,比如手机客户端、平板客户端和电视客户端,它们实现了观察者接口,并在接收到更新通知时更新天气信息:

class MobileClient : public Observer {
public:
    void update(string weatherInfo) override {
        cout << "Mobile client: Weather info updated - " << weatherInfo << endl;
        // 更新手机客户端上的天气信息
    }
};

class TabletClient : public Observer {
public:
    void update(string weatherInfo) override {
        cout << "Tablet client: Weather info updated - " << weatherInfo << endl;
        // 更新平板客户端上的天气信息
    }
};

class TVClient : public Observer {
public:
    void update(string weatherInfo) override {
        cout << "TV client: Weather info updated - " << weatherInfo << endl;
        // 更新电视客户端上的天气信息
    }
};

接下来,我们定义主题接口 Subject,其中包含了注册、删除和通知观察者的方法:

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

然后,我们创建具体的主题类 WeatherStation,它实现了主题接口,并维护了一组观察者对象,并在天气信息更新时通知所有观察者:

class WeatherStation : public Subject {
private:
    vector<Observer*> observers;
    string weatherInfo;

public:
    void registerObserver(Observer* observer) override {
        observers.push_back(observer);
    }

    void removeObserver(Observer* observer) override {
        // 从观察者列表中移除指定的观察者
    }

    void notifyObservers() override {
        for (Observer* observer : observers) {
            observer->update(weatherInfo);
        }
    }

    void setWeatherInfo(const string& newWeatherInfo) {
        weatherInfo = newWeatherInfo;
        notifyObservers();  // 当天气信息更新时通知观察者
    }
};

在客户端代码中,我们可以创建主题对象和观察者对象,将观察者注册到主题中,并模拟天气信息的更新:

int main() {
    WeatherStation weatherStation;
    MobileClient mobileClient;
    TabletClient tabletClient;
    TVClient tvClient;

    weatherStation.registerObserver(&mobileClient);
    weatherStation.registerObserver(&tabletClient);
    weatherStation.registerObserver(&tvClient);

    weatherStation.setWeatherInfo("Sunny");  // 模拟天气信息更新

    return 0;
}

在上述示例中,我们创建了一个天气预报系统,通过观察者模式实现了天气信息的推送功能。天气站(主题对象)在获取到天气信息后,通过通知观察者的方式,自动更新所有订阅了天气预报的客户端。

3 总结

观察者模式的优点在于它实现了主题和观察者对象之间的解耦,主题对象不需要了解观察者的具体细节,只需维护观察者对象的注册和通知即可。这样使得主题对象和观察者对象可以独立变化,互相不影响,同时也支持了广播通知,主题对象的状态更新会自动通知到所有的观察者。