【C++设计模式之观察者模式:行为型】分析及示例

简介

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

描述

观察者模式由两个核心件组成:主题(Subject)和观察者(Observer)。主题是一个可被观察的对象,它维护了一个观察者列表,可以动态地添加、删除和通知观察者。观察者是依赖于主题的对象,当主题发生变化时,观察者会自动更新自己的状态。

原理

观察者模式通过定义了主题和观察者之间的接口,使得主题和观察者可以彼此独立地进行交互。当主题的状态发生变化时,它会通知所有的观察者,而观察者会根据主题的通知进行相应的更新。

类图

【C++设计模式之观察者模式:行为型】分析及示例_第1张图片

Subject:目标类,它是一个抽象类,也是所有目标对象的父类。它用一个列表记录当前目标对象有哪些观察者对象,并提供增加、删除观察者对象和通知观察者对象的接口。
Observer:观察者类,它也是一个抽象类,是所有观察者对象的父类;它为所有的观察者对象都定义了一个名为update的方法(也叫成员函数)。当目标对象的状态改变时,它就是通过调用它的所有观察者对象的update方法来通知它们的。
ConcreteSubject:具体目标类,可以有多个不同的具体目标类,它们同时继承Subject类。一个目标对象就是某个具体目标类的对象,一个具体目标类负责定义它自身的事务逻辑,并在状态改变时通知它的所有观察者对象。
ConcreteObserver:具体观察者类,可以有多个不同的具体观察者类,它们同时继承Observer类。一个观察者对象就是某个具体观察者类的对象。每个具体观察者类都要重定义Observer类中定义的update方法,在该方法中实现它自己的任务逻辑,当它被通知的时候(目标对象调用它的update方法)就执行自己特有的任务。

示例

假设有一个天气预报系统,其中天气数据是主题,用户界面、手机App电视等是观察者。当天气数据更新时,所有的观察者都能够收到通知并更新自己的内容。

C++示例代码如下:

#include 
#include 

// 主题接口
class Subject {
public:
    virtual void attach(Observer* observer) = 0;
    virtual void detach(Observer* observer) = 0;
    virtual void notify() = 0;
};

// 观察者接口
class Observer {
public:
    virtual void update(const std::string& message) = 0;
};

// 具体主题
class WeatherData : public Subject {
public:
    void attach(Observer* observer) override {
        observers.push_back(observer);
    }

    void detach(Observer* observer) override {
        for (auto it = observers.begin(); it != observers.end(); ++it) {
            if (*it == observer) {
                observers.erase(it);
                break;
            }
        }
    }

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

    void setMessage(const std::string& message) {
        this->message = message;
        notify();
    }

private:
    std::vector<Observer*> observers;
    std::string message;
};

// 具体观察者
class UserInterface : public Observer {
public:
    void update(const std::string& message override {
        std::cout << "User Interface: " << message << std::endl;
    }
};

class MobileApp : public Observer {
public:
    void update(const std::string& message) override {
        std::cout << "Mobile App: " << message << std::endl;
    }
};

class TV : public Observer {
public:
    void update(const std::string& message) override {
        std::cout << "TV: " << message << std::endl;
    }
};

// 使用示例
int main() {
    WeatherData weatherData;
    UserInterface userInterface;
    MobileApp mobileApp;
    TV tv;

    weatherData.attach(&userInterface);
    weatherData.attach(&mobileApp);
    weatherData.attach(&tv);

    weatherData.setMessage("The is sunny.");

    weatherData.detach(&mobileApp);

    weatherData.setMessage("The weather is rainy");
    return 0;
}

输出结果

User Interface: The weather is sunny.
Mobile App: The weather is sunny.
TV: The is sunny.
User Interface: The weather is rainy.
TV: The weather is rainy.

解释

在上述示例中,主题接口(Subject)定义了操作观察者的方法,包括添加观察者、删除观察者和通知观察者。
具体主题(WeatherData)实现了主题接口,并维护了一个观察者列表。
观察者接口(Observer)定义了观察者的更新方法,具体观察者(UserInterface、MobileApp、TV)实现了观察者接口,并根据主题的通知进行相应的更新。

在示例中,创建了一个天气数据对象(WeatherData)作为主题,然后创建了三个观察者(UserInterface、MobileApp、TV)。将观察者添加到天气数据对象的观察者列表中,然后模拟天气数据发生变化,通过调用主题的notify方法通知所有的观察者。察者接收到通知后,会调用自己的update方法进行相应的更新操作。

结论

结论观察者模式通过定义了一种一对多的依赖关系,使得主题和观察者之间能够彼此独立地进行交互。它实现了对象间的解耦,当一个对象的状态发生变化时,所有依赖它的对象都能够自动收到通知并进行相的更新。

观察者模式适用场景:

  • 当一个对象的改变需要同时通知其他对象,并且不道具体有多少个对象需要通知时,可以使用观察者模式实现松散的耦合。
  • 当一个对象需要将自己的改变通知给其他对象,但是又希望避免耦合时,可以使用观察者模式。

观察者模式常见的应用场景包括事件驱动系统、GUI界面组件、消息队列系统等。

你可能感兴趣的:(Qt记录,设计模式之C++,c++,c++,设计模式,观察者模式)