9.观察者模式
2015-06-11 17:19
106 查看
1.说明
请参阅该系列第一篇文章。
2.观察者模式说明
观察者模式:定义了一种一对多的关系,让多个观察者对象监听某一主题对象,这个主体对象发生改变时,会通知观察者对象,使他能够自动更新自己
特点:将一个系统分割成一系列相互协作的类是一个很不好的副作用,那就是需要维护相关对象的一致性,我们不希望为了维护类的一致性而使类紧密耦合,这样会给维护,扩展,重用带来很多不便。
使用场景:当一个对象的改变需要需要同时改变其他对象,而且他不知道有多少个对象需要改变,这个时候就应该使用观察者模式,发出通知即可
作用:解除类之间的耦合,让耦合的双方都依赖于抽象,而不是具体的。
另外一种重要的方式:使用委托(待看)
委托对象所搭载的方式,必须具备于原来的有相同的形式,参数列表,返回值类型
公司项目就是通过观察者模式构建的,要扩展的时候,直接进行挂载,感觉很方便
3.UML
4.代码
代码背景:
在一个公司中,有老板,leader,员工A,B。老板管理leader,A,B。Leader管理A,B。A,B的上级有leader,老板,当其中任意一个对象状态发生改变,A,B状态也发生改变。在真正的项目中可能不会这么复杂,此处只是模拟现实中状况
请参阅该系列第一篇文章。
2.观察者模式说明
观察者模式:定义了一种一对多的关系,让多个观察者对象监听某一主题对象,这个主体对象发生改变时,会通知观察者对象,使他能够自动更新自己
特点:将一个系统分割成一系列相互协作的类是一个很不好的副作用,那就是需要维护相关对象的一致性,我们不希望为了维护类的一致性而使类紧密耦合,这样会给维护,扩展,重用带来很多不便。
使用场景:当一个对象的改变需要需要同时改变其他对象,而且他不知道有多少个对象需要改变,这个时候就应该使用观察者模式,发出通知即可
作用:解除类之间的耦合,让耦合的双方都依赖于抽象,而不是具体的。
另外一种重要的方式:使用委托(待看)
委托对象所搭载的方式,必须具备于原来的有相同的形式,参数列表,返回值类型
公司项目就是通过观察者模式构建的,要扩展的时候,直接进行挂载,感觉很方便
3.UML
4.代码
代码背景:
在一个公司中,有老板,leader,员工A,B。老板管理leader,A,B。Leader管理A,B。A,B的上级有leader,老板,当其中任意一个对象状态发生改变,A,B状态也发生改变。在真正的项目中可能不会这么复杂,此处只是模拟现实中状况
//观察者基类 #ifndef __SUBJECT_H #define __SUBJECT_H #include <iostream> #include <list> #include "Observer.h" class CSubject { public: void add(CObserver* obser) { m_objlist.push_back(obser); } void del(CObserver* obser) { for (std::list<CObserver*>::iterator it=m_objlist.begin(); it!=m_objlist.end(); it++) { if ((*it)->getname() == obser->getname()) { m_objlist.erase(it); break; } } } void notify() { for (std::list<CObserver*>::iterator it=m_objlist.begin(); it!=m_objlist.end(); it++) { (*it)->notify(); } } virtual std::string get_subject_status() = 0; virtual int get_subflag() = 0; private: std::list<CObserver*> m_objlist; }; #endif //观察者 大boss #ifndef __BIGBOSS_H #define __BIGBOSS_H #include "Subject.h" class CBigBoss:public CSubject { public: CBigBoss(std::string name) { m_flag = 0; m_name = name; } std::string get_subject_status() { return "BigBoss BACK"; } void action() { m_flag = 1; notify(); m_flag = 0; } int get_subflag() { return m_flag; } private: std::string m_name; int m_flag; }; #endif //即是观察者也是统治者的 TM leader #ifndef __BOSS_H #define __BOSS_H #include "Subject.h" #include "Observer.h" class CBoss:public CSubject,public CObserver { public: CBoss(std::string name) { m_flag = 0; m_name = name; } std::string get_subject_status() { return "TM Leader BACK"; } void action() { m_flag = 1; notify(1); m_flag = 0; } int get_subflag() { return m_flag; } std::string getname() { return m_name; } public: void add_sub(CSubject* ober) { m_sublist.push_back(ober); } void notify(int x) { CSubject::notify(); } void notify() { //大老板发通知后,拍着马屁也发通知 std::cout<<"I recved big boss notify"<<std::endl; CSubject::notify(); for (std::list<CSubject*>::iterator it=m_sublist.begin(); it!=m_sublist.end(); it++) { if ((*it)->get_subflag()) { std::cout<<(*it)->get_subject_status()<<" "<<m_name.c_str()<<" 赶快努力工作"<<std::endl; } } } private: std::list<CSubject*> m_sublist; std::string m_name; int m_flag; }; #endif //通知者基类 #ifndef __OBSERVER_H #define __OBSERVER_H //存在互相依赖,为了方便直接注释掉 //#include "Subject.h" #include <iostream> #include <string> class CObserver { public: virtual void notify() = 0; virtual std::string getname() = 0; //virtual void add_sub(CSubject* ober)=0; }; #endif //通知者员工A #ifndef __STAFFA_H #define __STAFFA_H #include <iostream> #include <list> #include "Observer.h" #include "Subject.h" class CStaffA:public CObserver { public: CStaffA(std::string name) { m_name = name; } void add_sub(CSubject* ober) { m_sublist.push_back(ober); } void notify() { for (std::list<CSubject*>::iterator it=m_sublist.begin(); it!=m_sublist.end(); it++) { if ((*it)->get_subflag()) { std::cout<<(*it)->get_subject_status()<<" "<<m_name.c_str()<<" 赶快努力工作"<<std::endl; } } } std::string getname() { return m_name; } private: std::string m_name; std::list<CSubject*> m_sublist; }; #endif //通知者员工B #ifndef __STAFFB_H #define __STAFFB_H #include <iostream> #include <list> #include "Observer.h" #include "Subject.h" class CStaffB:public CObserver { public: CStaffB(std::string name) { m_name = name; } void add_sub(CSubject* ober) { m_sublist.push_back(ober); } void notify() { for (std::list<CSubject*>::iterator it=m_sublist.begin(); it!=m_sublist.end(); it++) { if ((*it)->get_subflag()) { std::cout<<(*it)->get_subject_status()<<" "<<m_name.c_str()<<" 赶快努力工作"<<std::endl; } } } std::string getname() { return m_name; } private: std::string m_name; std::list<CSubject*> m_sublist; }; #endif //client调用 #include <iostream> #include "Subject.h" #include "BigBoss.h" #include "Boss.h" #include "StaffA.h" #include "StaffB.h" // 这个代码调了好久,在list容器中存放的为指针,那么在使用的时候即为双重指针,我又搞忘了 //这个代码很有意思,值得好好分析 //采用文本编辑的时候,确实容易出现很多低级错误,拼写等 int main(void) { CBigBoss* bigboss = new CBigBoss("zhangpg"); CBoss* leader = new CBoss("zhangkuan"); CStaffA* staffa = new CStaffA("xiaoli"); CStaffB* staffb = new CStaffB("Lucy"); staffa->add_sub(bigboss); staffa->add_sub(leader); staffb->add_sub(bigboss); staffb->add_sub(leader); bigboss->add(leader); bigboss->add(staffa); bigboss->add(staffb); leader->add(staffa); leader->add(staffb); leader->add_sub(bigboss); std::cout<<"this is bigboss action."<<std::endl; bigboss->action(); std::cout<<"\n\nthis is leader action"<<std::endl; leader->action(); return 0; }
相关文章推荐
- Openstack中为虚拟机使用CDROM光驱设备
- Looksery Cup 2015——AFace Detection
- SVG 路径(path)
- Java 8 中的 Streams API 详解
- LeetCode 之 Sort Colors — C 实现
- 将图片转换为NSData
- 快速了解Scala技术栈
- Android开发之如何保证Service不被杀掉(broadcast+system/app)
- 转加解密算法的一些概述总结
- 2015 辽宁省赛C题 dp+单调队列优化
- 构建素数表
- "The method findViewById(int) is undefined for ..."
- 使用svn删除Xcode工程中的文件
- DHCP (Dynamic Host Configuration Protocol)
- android手机使用ksoap2发送soap请求,服务端接收参数为null
- Android 通过图库选择图片提示找不到路径 open failed: EROFS (Read-only file system)
- jQuery选择器全面总结
- Leetcode[104]-Maximum Depth of Binary Tree
- java中的clone()方法的研究---(7)如何编写正确的clone()方法:Date, Timestamp
- 策略模式学习笔记