首页 > 代码库 > (一)观察者模式-C++实现
(一)观察者模式-C++实现
观察者模式:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。
它有四种角色:
主题(Subject):一个接口,规定了具体主题需要实现的方法。
观察者(Observer):也是一个接口,规定了具体观察者用来更新数据的方法。
具体主题:实现主题接口的一个实例,比如本例中的“就业通知中心”;里面会维护一个具体观察者的集合。本文使用STL中的list。
具体观察者:实现观察者的一个实例,会包含存放主题的引用或者指针。
使用C++实现如下:
包含5个文件,头文件两个:主题类(Subject.h)观察者类(Observer.h)
源文件两个:主题类(Subject.cpp)观察者类(Observer.h)
一个测试文件。
//Subject.h
#ifndef _SUBJECT_H_ #define _SUBJECT_H_ #include "Observer.h" #include <list> #include <string> using namespace std; class Observer;//注意C++中虽然包含了头文件这里也需要声明 typedef list<Observer*> myList; class Subject{ public: Subject(){} virtual ~Subject(){} virtual void addObserver(Observer* o) = 0; virtual void deleteObserver(Observer* o) = 0; virtual void notifyObservers() = 0; }; class SeekJobCenter : public Subject { public: SeekJobCenter(); ~SeekJobCenter(){} void addObserver(Observer* o); void deleteObserver(Observer* o); void notifyObservers(); void giveNewMessage(string str); private: string mess; bool changed; myList personList; }; #endif
//Subject.cpp
//具体的主题 #include "stdafx.h" #include "Subject.h" #include "Observer.h" #include <list> SeekJobCenter::SeekJobCenter() { mess = ""; changed = false; } void SeekJobCenter::addObserver(Observer* o) { list<Observer*>::iterator it; //判断原始维护的list中是否存在添加的对象 it = find(personList.begin(), personList.end(), o); if (it == personList.end())//不存在 { personList.push_back(o); } return; } void SeekJobCenter::deleteObserver(Observer* o) { list<Observer*>::iterator it; it = find(personList.begin(), personList.end(), o); if (it != personList.end())//存在 { personList.remove(*it); delete(*it); } return; } void SeekJobCenter::notifyObservers() { list<Observer*>::iterator it; if (changed) { for (it = personList.begin(); it != personList.end(); ++it) { (*it)->hearTelephone(mess); } changed = false; } return; } void SeekJobCenter::giveNewMessage(string str) { if (0 == strcmp(str.c_str(), mess.c_str())) { changed = false; } else { mess = str; changed = true; } return; }
//Observer.h
#ifndef _OBSERVER_H_ #define _OBSERVER_H_ #include <string> #include <iostream> #include <list> #include "Subject.h" using namespace std; class Subject; /* 观察者基类 */ class Observer { public: Observer(){}; virtual ~Observer(){}; virtual void hearTelephone(string heardMess) = 0; }; class UniversityStudent : public Observer { public: UniversityStudent(Subject* subject); virtual ~UniversityStudent(){}; void hearTelephone(string heardMess); private: Subject* subject; }; class HaiGui : public Observer { public: HaiGui(Subject *subject); virtual ~HaiGui(){}; void hearTelephone(string heardMess); private: Subject *subject; }; #endif
//Observer.cpp
#include "stdafx.h" #include "Observer.h" #include "Subject.h" UniversityStudent::UniversityStudent(Subject* subject) { if (NULL != subject) { this->subject = subject; } else { return; } subject->addObserver(this); } void UniversityStudent::hearTelephone(string heardMess) { std::cout << "I am a university student" << std::endl; std::cout << "I hear message is " << heardMess << std::endl; return; } HaiGui::HaiGui(Subject* subject) { if (NULL != subject) { this->subject = subject; } else { return; } subject->addObserver(this); } void HaiGui::hearTelephone(string heardMess) { std::cout << "I am a HaiGui" << std::endl; std::cout << "I hear message is " ; cout << heardMess << endl; return; }
最后一个测试的文件:
#include "stdafx.h" #include "Observer.h" #include "Subject.h" int _tmain(int argc, _TCHAR* argv[]) { SeekJobCenter *center = new SeekJobCenter(); UniversityStudent *chengchaolee = new UniversityStudent(center); HaiGui *haigui = new HaiGui(center); center->giveNewMessage("I need a cook"); center->notifyObservers(); center->giveNewMessage("I need a xxxx"); center->notifyObservers(); delete center; delete chengchaolee; delete haigui; return 0; }
定义两个具体的观察者,并且以具体主题作为参数,代表它观察的对象,然后当主题推送数据时,观察者就会收到消息,即“推数据”的方式,当然还有一种观察者模式采用的是拉数据,即由观察者自己定义需要什么数据,主题在notify的时候并不传递参数而是在观察者更新数据时,将Subject向下转换为具体Subject,从而获取其中相应的数据,这种方式叫做“拉数据”。
值得注意的是,C++在实现的时候,采用list存储具体观察者,需要使用list<Observer*>类型,即使用指针。不然会编译不通过,因为Observer是虚基类,无法实例化。
(一)观察者模式-C++实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。