观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,
这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
最常见的一个例子就是:对同一组数据进行统计分析时候,
我们希望能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。
Observer.h
#ifndef _OBSERVER_H_
#define _OBSERVER_H_
#include <list>
#include <iostream>
using namespace std;
class observer;
class subject
{
public:
void attach(observer *obs);
void detach(observer *obs);
void setValue(int value);
int getValue();
void notify();
private:
list<observer *> ls;
int value_;
};
class observer
{
public:
observer(subject *mod, int div);
virtual ~observer();
virtual void update() = 0;
protected:
subject * getSubject();
int getDivisor();
private:
subject *model_;
int divisor_;
};
class DivObserver : public observer
{
public:
DivObserver(subject *mod, int div);
void update();
};
class ModObserver : public observer
{
public:
ModObserver(subject *mod, int div);
void update();
};
#endif
Observer.cpp
#include "Observer.h"
#include <algorithm>
using std::cout;
using std::endl;
void subject::attach(observer *obs)
{
ls.push_back(obs);
}
void subject::detach(observer *obs)
{
list<observer *>::iterator it;
it = find(ls.begin(), ls.end(), obs);
if (it != ls.end())
ls.erase(it);
}
void subject::setValue(int value)
{
value_ = value;
notify();
}
int subject::getValue()
{
return value_;
}
void subject::notify()
{
for (list<class observer *>::iterator it = ls.begin(); it != ls.end(); ++it)
(*it)->update();
}
observer::observer(subject *mod, int div) : model_(mod), divisor_(div)
{
model_->attach(this);
}
observer::~observer()
{
model_->detach(this);
}
subject * observer::getSubject()
{
return model_;
}
int observer::getDivisor()
{
return divisor_;
}
DivObserver::DivObserver(subject *mod, int div) : observer(mod, div)
{
}
void DivObserver::update()
{
int v = getSubject()->getValue();
int d = getDivisor();
cout << v << "/" << d << " = " << v/d << endl;
}
ModObserver::ModObserver(subject *mod, int div) : observer(mod, div)
{
}
void ModObserver::update()
{
int v = getSubject()->getValue();
int d = getDivisor();
cout << v << "%" << d << " = " << v%d << endl;
}
main.cpp
#include "Observer.h"
int main()
{
subject sub;
DivObserver d1(&sub, 3);
ModObserver m1(&sub, 4);
sub.setValue(15);
return 0;
}