C++ 观察者模式
2016-06-26 22:54
295 查看
C++ 观察者模式
Muduo不好啃,也怪自己之前没学过设计模式,如今只能临时抱佛脚了。简介
什么是观察者模式?在学习这个设计模式之前,先要知道一件事情:回调函数(callback),在知乎上关于回调函数有一个形象的比喻:你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。回答完毕。
作者:常溪玲
链接:https://www.zhihu.com/question/19801131/answer/13005983
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
经过一天的研究,我发现观察者模式跟回调函数很像,在一块理解起来很方便。
观察者模式又叫做发布-订阅模式,跟回调类似,接着上面的例子,你就是观察者,而店员就是对象,当到货之后(状态发生变化),就通知观察者。
关于具体概念,菜鸟还是不长篇大论了,还是偏理解为主,可以参考:http://blog.csdn.net/wuzhekai1985/article/details/6674984
实现
对muduo 源码中的~/recipes/thread/test/observer.cc做了一些修改。主要是进行简单的解耦操作。
Observer观察者
//Observer.h #ifndef __OBSERVER_H__ #define __OBSERVER_H__ #include <iostream> #include <string> #include "Observable.h" class Observable; class Observer//抽象类 { public: virtual ~Observer(); virtual void update()=0;//纯虚函数 void observe(Observable *s);//订阅 protected: Observable* __subject;//订阅的对象 }; #endif
//Observer.cpp #include "Observer.h" #include "Observerable.h" void Observer::observe(Observable*s) { s->__register(this);//类似于注册回调函数,这里传递的是观察者地址。 __subject=s;//观察者通过指针访问到它观察的对象 } Observer::~Observer() { __subject->__unregister(this); }
被观察对象
//Observable.h #ifndef __OBSERVABLE_H__ #define __OBSERVABLE_H__ #include <iostream> #include <string> #include <algorithm> #include <vector> #include "Observer.h" class Observer; class Observable { public: Observable(){} virtual ~Observable(){} void __register(Observer *x); void __unregister(Observer *x); void notify();//通知观察者 virtual void status(const std::string &s);//set状态 virtual std::string status();//get状态 private: std::vector<Observer*> __observers;//记录所有的观察者 protected: std::string __status; }; #endif
//Observable.cpp #include "Observable.h" #include "Observer.h" void Observable::notify() { for(int i=0;i<__observers.size();++i)//通知所有观察者 { Observer * x = __observers[i]; if(NULL!=x) { x->update(); } } } void Observable::__register(Observer*x) { __observers.push_back(x); } void Observable::__unregister(Observer *x) { std::vector<Observer*>::iterator it = std::find(__observers.begin(),__observers.end(),x); if(it != __observers.end())//found! { std::swap(*it,__observers.back()); __observers.pop_back(); } } void Observable::status(const std::string &s) { __status=s; } std::string Observable::status() { return __status; }
main函数
在main函数中,对观察者和被观察的对象分别派生类。其中,观察者为订阅博客的人。
被观察对象为CSDN博客的博主。
观察者订阅之后,当有博客更新,就推送给其观察者。
//main.cpp #include "Observer.h" #include "Observable.h" class BlogObserver : public Observer//订阅博客的人 { private: std::string __name; public: BlogObserver(std::string name):__name(name){} virtual void update(); }; class BlogCSDN : public Observable//博主 { private: std::string __name;//blog name public: BlogCSDN(std::string name ):__name(name){} ~BlogCSDN(){} void status(const std::string &s); std::string status(); }; void BlogCSDN::status(const std::string &s)//重写,更新博客 { __status="Blog Name: "+__name+" Content: "+s; } std::string BlogCSDN::status() { return __status; } void BlogObserver::update()//更新(收到消息) { std::string status=__subject->status(); std::cout<<status<<std::endl; std::cout<<__name<<" is notified"<<std::endl; } int main() { Observer * p = new BlogObserver("SomeOne");//观察者1号 Observer * q = new BlogObserver("SomeOne2");//观察者2号 Observable *sub1= new BlogCSDN("zhangxiao93") ;//博主 sub1->status("UNIX Network Programming(1)");//博主更新博文 //观察者订阅 p->observe(sub1); q->observe(sub1); sub1->notify();//通知所有观察者 delete p; delete q; delete sub1; return 0; }
Makefile
PROGS = main CLEANFILES = core core.* *.core *.o temp.* *.out typescript* \ *.lc *.lh *.bsdi *.sparc *.uw all: ${PROGS} CXXFLAGS= -Wall -g OBJ=main.o Observer.o Observable.o LDFLAGS= main: ${OBJ} ${CXX} ${CXXFLAGS} $^ -o $@ ${LDFLAGS} clean: rm -f ${PROGS} core *.o .PHONY: clean all
参考
1.《大话设计模式》2.http://blog.csdn.net/wuzhekai1985/article/details/6674984
3.muduo源码
相关文章推荐
- 能否通过内嵌汇编修改C++中const常量的值
- C++类的继承与派生
- 【C++】堆内存和栈内存详解
- C++进阶教程之模板2--简单模板类(霜之小刀 附视频)
- c语言 两个变量值交换
- 【C++】对深拷贝与浅拷贝的再次理解
- C++ Primer Plus 第六版_编程练习(5)(Chapter_five 6-10)
- C语言随堂笔记---条件分支结构
- 一起talk C栗子吧(第一百六十七回:C语言实例--控制终端字符颜色)
- C语言随堂笔记---数据类型、变量、运算符
- c语言学习笔记38之字符指针
- C语言随堂笔记---第一课
- C语言随堂笔记---数据处理和交互式输入
- c语言由键盘输入不定长数组的元素
- caffe c++
- see C++ for the first(初识C++)
- 【C语言】单链表相关面试题(一)
- C++ - 计蒜客 - 大钉骑马走江湖(bfs)
- C++中的重载,重写, 重定义 差别
- 回调函数c++实现。