一、介绍
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时会通知所有观察者对象,使他们能够自动更新自己。
**这种交互也称为发布-订阅,**发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。
二、实现
1.主题
#ifndef _TEACHERSUBJECT_HEAD_H
#define _TEACHERSUBJECT_HEAD_H
#include <iostream>
using namespace std;
class StudentObserver;
class TeacherSubject
{
public:
virtual void add(StudentObserver *student) = 0;
virtual void remove(StudentObserver *student) = 0;
virtual void notify(void) = 0;
void setMessage(const string &message) {
this->message = message;
}
string getMessage(void) const {
return message;
}
private:
string message;
};
#endif
//------------------------------------------------------
#ifndef _CPPTEACHERSUBJECT_HEAD_H
#define _CPPTEACHERSUBJECT_HEAD_H
#include "TeacherSubject.hpp"
#include <list>
#include "StudentObserver.hpp"
class CppTeacherSubject:public TeacherSubject
{
public:
void add(StudentObserver *student) {
obseverList.push_back(student);
}
void remove(StudentObserver *student) {
obseverList.remove(student);
}
void notify(void) {
for(list<StudentObserver *>::iterator it = obseverList.begin();
it != obseverList.end(); it ++) {
(*it)->update();
}
}
private:
list<StudentObserver *> obseverList;
};
#endif
2.观察者
#ifndef _STUDENTOBSERVER_HEAD_H
#define _STUDENTOBSERVER_HEAD_H
class TeacherSubject;
class StudentObserver
{
public:
StudentObserver(TeacherSubject *subject) {
this->subject = subject;
}
virtual void update(void) = 0;
protected:
TeacherSubject *subject;
};
#endif
//------------------------------------------------------
#ifndef _GAMESTUDENTOBSERVER_HEAD_H
#define _GAMESTUDENTOBSERVER_HEAD_H
#include "StudentObserver.hpp"
class GameStudentObserver:public StudentObserver
{
public:
GameStudentObserver(TeacherSubject *subject):StudentObserver(subject) {
}
void update(void) {
cout << "Can not play game,Go to class" << endl;
cout << subject->getMessage() << endl;
}
};
#endif
//------------------------------------------------------
#ifndef _SLEEPSTUDENTOBSERVER_HEAD_H
#define _SLEEPSTUDENTOBSERVER_HEAD_H
#include "StudentObserver.hpp"
class SleepStudentObserver:public StudentObserver
{
public:
SleepStudentObserver(TeacherSubject *subject):StudentObserver(subject) {
}
void update(void) {
cout << "Can not sleep,Go to class" << endl;
cout << subject->getMessage() << endl;
}
};
#endif
4.使用
#include "CppTeacherSubject.hpp"
#include "SleepStudentObserver.hpp"
#include "GameStudentObserver.hpp"
int main(int argc, const char *argv[])
{
CppTeacherSubject *teacherSubject = new CppTeacherSubject();
SleepStudentObserver *sleepObserver = new SleepStudentObserver(teacherSubject);
GameStudentObserver *gameObserver = new GameStudentObserver(teacherSubject);
teacherSubject->add(sleepObserver);
teacherSubject->add(gameObserver);
cout << "-----------------------------" << endl;
teacherSubject->setMessage("Start Cpp Class");
teacherSubject->notify();
return 0;
}
三、优缺点
优点:
-
观察者和被观察者之间建立了一个抽象的耦合。
-
观察者模式支持广播通信
缺点:
-
观察者之间有过多的细节依赖、提高时间消耗及程序的复杂度。
-
如果在观察者和观察目标之间存在循环依赖,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。