<aside> 💡

观察者模式(Observer):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,是它们能够自动更新自己

</aside>

结构图

image.png

观察者模式的特点

观察者模式的不足

题目

https://kamacoder.com/problempage.php?pid=1075

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// 抽象的观察者类
class Observer{
public:
    // 收到通知者的通知后进行更新的方法
    virtual void update(int curTime) = 0;
};

// 抽象主题类,一个接口
class Subject{
public:
    // 添加、删除观察者
    virtual void addObserver(Observer* observer) = 0;
    virtual void removeObserver(Observer* observer) = 0;
    // 通知所有观察者
    virtual void notify() = 0;

    virtual ~Subject() = default;
};

// 具体的主题类
class ConcreteSubject: public Subject{
private:
    int curTime = 0;
    vector<Observer*> observers;
public:
    void addObserver(Observer* observer) override {
        observers.push_back(observer);
    }

    void removeObserver(Observer* observer) override {
        auto it = find(observers.begin(), observers.end(), observer);
        if(it != observers.end()){
            observers.erase(it);
        }
    }

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

    // tick()实现了时间的自增,并调用notify()通知所有观察者
    void tick(){
        curTime = (curTime + 1) % 24;
        notify();
    }
};

// 具体的观察者类
class ConcreteObserver: public Observer{
private:
    string name;
    ConcreteSubject* subject;
public:
    ConcreteObserver(string name, ConcreteSubject* subject): name(name), subject(subject){}

    void update(int curTime) override {
        cout << name << ' ' << curTime << endl;
    }
};

int main(){
    ConcreteSubject xiaominSubject;

    int n;
    cin >> n;
    for(int i = 0; i < n; ++i){
        string name;
        cin >> name;
        xiaominSubject.addObserver(new ConcreteObserver(name, &xiaominSubject));
    }

    int updateTimes;
    cin >> updateTimes;
    for(int i = 0; i < updateTimes; ++i){
        xiaominSubject.tick();
    }

    return 0;
}