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!