设计模式实现——观察者模式
2016-09-04 15:52
351 查看
转载请注明t1234xy4原创:http://blog.csdn.net/t1234xy4/article/details/52432559#
观察者模式简介
又称发布——订阅模式,主要用于类对象之间消息通知。当主要对象发生信息变更后,与之相关联的信息也应该变更显示。主要的操作:
1、先创建主体subject;
2、创建观察者,同时告诉它要关注的主体subuject。
3、主体subject要知道哪些人关注了它,因此需要维护一个list。同时将观察者放入list中。操作位Attach()。如果不关注了需要Detach()。
4、观察者要主动拉取信息,pull()。
这个类图比较简单,但实现比较麻烦。实现需要注意:
1、同一个观察者不要attach两次或两次以上。(除非你希望给同一个观察者发送多次重复的信息,但没多少意义)
2、如果一个实例提前消亡了,在消亡前应该Detach掉,否者下次发送消息将导致不可预知的风险。(当然每次发送消息的时候,可以对每一个实例是否存在检查)
3、其他的还没有遇到。
类图
代码
subject代码部分
#pragma once #include "Observer.h" #include <string> #include <iostream> #include <list> using namespace std; class ConcreteSubject{ public: ConcreteSubject(); virtual void Attach(Observer* ob); virtual void Dettch(Observer* ob); virtual void NotifyAll(); virtual void changeState(std::string _state); virtual std::string getState(); ~ConcreteSubject(); protected: std::string state; std::list<Observer *> _obList; };
#include "ConcreteSubject.h" ConcreteSubject::ConcreteSubject():state("one"){ } void ConcreteSubject::Attach(Observer* ob){ std::cout<<"Insert Observer:"<<ob->getObserverId()<<std::endl; std::list<Observer *>::iterator it; for(it=_obList.begin();it!=_obList.end();it++) if((*it)==ob){ std::cout<<" has been in the List"<<std::endl; return; } _obList.push_back(ob); } void ConcreteSubject::Dettch(Observer* ob){ std::cout<<"Observer "<<ob->getObserverId()<<" : "; _obList.remove(ob); std::cout<<"removed"; } void ConcreteSubject::NotifyAll(){ std::list<Observer *>::iterator it; for(it = _obList.begin();it!=_obList.end();it++) { (*it)->pull(); } } void ConcreteSubject::changeState(std::string _state){ state = _state; } std::string ConcreteSubject::getState(){ return state; } ConcreteSubject::~ConcreteSubject(){ std::cout<<"ConcreteSubject "<<std::endl; }
观察者部分
#pragma once #include "ConcreteSubject.h" #include <string> #include <iostream> class ConcreteObserver: public Observer{ protected: ConcreteObserver(void); public: ConcreteObserver(ConcreteSubject* _sub,int id); virtual void pull(); virtual int getObserverId(); ~ConcreteObserver(); private: ConcreteSubject* subject; int Id; };
#include "ConcreteObserver.h" ConcreteObserver::ConcreteObserver(){ } ConcreteObserver::ConcreteObserver(ConcreteSubject* _sub,int id):subject(_sub),Id(id){ } void ConcreteObserver::pull(){ std::cout <<"Observer "<<Id<<": "<< subject->getState() <<std::endl; } int ConcreteObserver::getObserverId(){ return Id; } ConcreteObserver::~ConcreteObserver(){ std::cout<<" ~ConcreteObserver :"<<Id<<std::endl; }
相关文章推荐
- spring添加事务管理
- 题目:旋转数组的最小数字
- MESPRO
- Android开发 Fiddler抓包
- 插入排序算法
- poj 3233Matrix Power Series(矩阵快速幂 二分求和 求累乘的和)
- ios开发之核心动画四:核心动画-Core Animation--CABasicAnimation基础核心动画
- 数学 求平行四边形的面积和坐标
- MyBatis学习之二:SQL语句映射文件(1)resultMap
- hadoop HA原理
- 浅析智能指针一
- xpath语法
- Python迭代器笔记
- 练习:WinForm 进程(创建、注销)
- gocode+auto-complete搭建emacs的go语言自动补全功能
- [bat] 批量删除文本文件的空行
- Python 学习笔记
- Android工具类--开关软键盘类
- Hololens入门之空间锚与场景保持
- 背包 贪心