C++设计模式---观察者模式

1、介绍

        观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,它的所有依赖者(观察者)都会自动收到通知并更新。

包含组件如下:

        (1)主题(Subject):主题是一个接口,可以把所有观察者对象登记到其观察者列表中,并且当它的内部状态发生改变时,会自动通知所有登记过的观察者对象。【在类内部建立一个vector记录所有的观察者,当主体发生变化时,遍历通知】。【一个抽象类】。

        (2)具体主题(ConcreteSubject):具体主题实现了主题接口,在内部状态发生改变时,会主动通知所有登记过的观察者对象。【抽象类的子类】。

        (3)观察者(Observer):观察者是一个接口,为所有的具体观察者定义一个更新接口,使得在得到主题的通知时更新自己。【一个抽象类】。

        (4)具体观察者(ConcreteObserver):具体观察者实现了观察者接口,该接口保持一个指向具体主题的引用,以便在主题状态发生改变时得到通知。【抽象类的子类】。

2、示例

#include <iostream>  
#include <list>  
#include <string>  

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

// 具体观察者1 
class ConcreteObserver1 : public Observer {
private:
    std::string name;
public:
    ConcreteObserver1(const std::string& name) : name(name) {}
    void update(const std::string& message) override {
        std::cout << name << " 1111 received: " << message << std::endl;
    }
};

// 具体观察者2 
class ConcreteObserver2 : public Observer {
private:
    std::string name;
public:
    ConcreteObserver2(const std::string& name) : name(name) {}
    void update(const std::string& message) override {
        std::cout << name << " 2222 received: " << message << std::endl;
    }
};

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

// 具体主题1 
class ConcreteSubject1 : public Subject {
private:
    std::list<Observer*> observers;
    std::string state;
public:
    // 添加观察者
    void attach(Observer* observer) override {
        observers.push_back(observer);
    }

    // 删除观察者
    void detach(Observer* observer) override {
        observers.remove(observer);
    }

    // 通知观察者
    void notifyObservers() override {
        for (auto observer : observers) {
            observer->update(state);
        }
    }

    // 设置状态
    void setState(const std::string& newState) {
        state = newState;
        notifyObservers();
    }
};

// 具体主题2
class ConcreteSubject2 : public Subject {
private:
    std::list<Observer*> observers;
    std::string state;
public:
    // 添加观察者
    void attach(Observer* observer) override {
        observers.push_back(observer);
    }

    // 删除观察者
    void detach(Observer* observer) override {
        observers.remove(observer);
    }

    // 通知观察者
    void notifyObservers() override {
        for (auto observer : observers) {
            observer->update(state);
        }
    }

    // 设置状态
    void setState(const std::string& newState) {
        state = newState;
        notifyObservers();
    }
};

int main() {
    ConcreteSubject1 subject1;
    ConcreteSubject2 subject2;
    Observer* observer1 = new ConcreteObserver1("Observer 1111");
    Observer* observer2 = new ConcreteObserver1("Observer 1112");

    Observer* observer3 = new ConcreteObserver2("Observer 2221");
    Observer* observer4 = new ConcreteObserver2("Observer 2222");

    subject1.attach(observer1);
    subject1.attach(observer2);
    subject1.attach(observer3);
    subject1.attach(observer4);

    subject1.setState("Hello, observers!");

    // 不再需要观察者时,应该将其从主题中分离并删除  
    subject1.detach(observer1);
    subject1.detach(observer4);

    subject1.setState("Hello, observers 2 and 3!");

    delete observer1;
    delete observer2;
    delete observer3;
    delete observer4;

    std::cout << "===============================================" << std::endl;
    Observer* observer5 = new ConcreteObserver1("Observer 1111");
    Observer* observer6 = new ConcreteObserver1("Observer 1112");

    Observer* observer7 = new ConcreteObserver2("Observer 2221");
    Observer* observer8 = new ConcreteObserver2("Observer 2222");

    subject2.attach(observer5);
    subject2.attach(observer6);
    subject2.attach(observer7);
    subject2.attach(observer8);

    subject2.setState("Hello, observers!");

    // 不再需要观察者时,应该将其从主题中分离并删除  
    subject2.detach(observer6);
    subject2.detach(observer7);

    subject2.setState("Hello, observers 5 and 8!");

    delete observer5;
    delete observer6;
    delete observer7;
    delete observer8;

    return 0;
}

结果:

Observer 1111 1111 received: Hello, observers!
Observer 1112 1111 received: Hello, observers!
Observer 2221 2222 received: Hello, observers!
Observer 2222 2222 received: Hello, observers!
Observer 1112 1111 received: Hello, observers 2 and 3!
Observer 2221 2222 received: Hello, observers 2 and 3!
===============================================
Observer 1111 1111 received: Hello, observers!
Observer 1112 1111 received: Hello, observers!
Observer 2221 2222 received: Hello, observers!
Observer 2222 2222 received: Hello, observers!
Observer 1111 1111 received: Hello, observers 5 and 8!
Observer 2222 2222 received: Hello, observers 5 and 8!

相关推荐

  1. c#观察设计模式

    2024-06-13 12:32:01       55 阅读
  2. C++ 设计模式观察模式

    2024-06-13 12:32:01       51 阅读
  3. C++ 设计模式观察模式

    2024-06-13 12:32:01       38 阅读
  4. C++设计模式---观察模式

    2024-06-13 12:32:01       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-13 12:32:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-13 12:32:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-13 12:32:01       82 阅读
  4. Python语言-面向对象

    2024-06-13 12:32:01       91 阅读

热门阅读

  1. Flutter状态管理

    2024-06-13 12:32:01       25 阅读
  2. ElasticSearch基本用法

    2024-06-13 12:32:01       33 阅读
  3. 【2024年计算机相关专业是否还值得选择】

    2024-06-13 12:32:01       32 阅读
  4. 理解JVM中的常量池

    2024-06-13 12:32:01       36 阅读
  5. GitLab中用户权限

    2024-06-13 12:32:01       30 阅读
  6. 面试题

    2024-06-13 12:32:01       29 阅读
  7. python调用web_service

    2024-06-13 12:32:01       31 阅读
  8. LVGL调试记录

    2024-06-13 12:32:01       31 阅读
  9. uniapp APP读取bin文件(仅测试安卓可用)

    2024-06-13 12:32:01       34 阅读
  10. python提取浮点数的小数部分-4种方法

    2024-06-13 12:32:01       31 阅读
  11. RIP协议

    2024-06-13 12:32:01       28 阅读
  12. freebsd 14.1 简易安全安装步骤

    2024-06-13 12:32:01       23 阅读
  13. 零撸项目:撸包看广告小游戏app开发源码

    2024-06-13 12:32:01       25 阅读
  14. C++中的模板方法模式

    2024-06-13 12:32:01       24 阅读