C++设计模式:观察者模式
观察者模式又叫做发布-订阅模式;
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动的更新自己。
有两大类(主题和观察者)一共四个角色
从上面我们可以看到,这里面包含了:
(1) 抽象主题/抽象被观察者(Subject)角色:将所有观察者对象保存在一个集合中,可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象
(2) 具体主题/具体被观察者(ConcreteSubject)角色:该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知
(3) 抽象观察者(Observer)角色:它定义了一个更新接口,使得在得到主题/被观察者更新时通知自己
(4) 具体观察者(ConcreteObserver)角色:实现抽象观察者定义的更新接口,以便在得到主题/被观察者更新时通知自己更新自身状态
其UML类图如下:
observer.cpp:
#include <iostream> #include <string.h> #include <stdio.h> #include <list> using namespace std; class Observer { public: virtual void update(){} virtual string getName() {return "";} }; class Subject { public: void enroll(Observer *observer); void detach(Observer *observer); void notify(); ~Subject(); private: list<Observer*> observers; }; class ConcreteSubject: public Subject { public: string getSubjectState(); void setSubjectState(const string &str); private: string subjectState; }; class ConcreteObserver:public Observer { public: ConcreteObserver(ConcreteSubject *subject, string name); void update(); string getName(); private: string name; string observerState; ConcreteSubject *subject; }; void Subject::enroll(Observer *observer) { observers.push_back(observer); } void Subject::detach(Observer *observer) { observers.remove(observer); } void Subject::notify() { list<Observer*>::iterator it = observers.begin(); while(it != observers.end()) { (*it)->update(); it++; } } Subject::~Subject() { printf("开始析构了\n"); list<Observer*>::iterator it = observers.begin(); while(it != observers.end()) { printf("开始删除: "); cout<<(*it)->getName()<<endl; delete *it; it++; } observers.clear(); } string ConcreteSubject::getSubjectState() { return subjectState; } void ConcreteSubject::setSubjectState(const string &str) { subjectState = str; } ConcreteObserver::ConcreteObserver(ConcreteSubject *subject, string name) { this->subject = subject; this->name = name; } void ConcreteObserver::update() { observerState = subject->getSubjectState(); cout<<"发布者更新东西了!!!订阅者: "<<name<<" 状态: "<<observerState<<endl; } string ConcreteObserver::getName() { return name; } int main() { ConcreteSubject *sub = new ConcreteSubject; sub->enroll(new ConcreteObserver(sub, "第一个粉丝")); sub->enroll(new ConcreteObserver(sub, "第二个粉丝")); sub->enroll(new ConcreteObserver(sub, "第三个粉丝")); sub->setSubjectState("刘亦菲"); sub->notify(); printf("<<------------------------------------->>\n"); sub->enroll(new ConcreteObserver(sub, "王二麻子")); sub->setSubjectState("刘诗诗"); sub->notify(); cout<<endl; delete sub; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧