观察者模式简介
观察者模式,简单的说就是围观,美利坚、南韩、日本围观金家三胖的动作,时刻准备着拦截nuclear weapon。
书本上的定义:
定义了对象之间的一对多依赖,这样以来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动更新。
应用观察者模式的好处:
第一,反向依赖,观察者只需要注册回调函数,在状态发生变化时观察者的更新行为得到执行;
第二,一对多的依赖,被观察的对象可以直接影响到所有的观察者;
类图
两个基类:
被观察对象Observable,提供维护观察者的方法
观察者Observer,做好自己,在状态改变时做对的事update()
c++实现
基类Observable
class Observable {
public:
void registerObserver(Observer *o);
void removeObserver(Observer *o);
void notifyObservers(ObserverArg *arg);
void setChanged();
private:
bool observerExists(Observer *o);
private:
bool changed;
std::list<Observer*> observers;
};
void Observable::registerObserver(Observer* o)
{
if (!observerExists(o))
observers.push_back(o);
}
void Observable::removeObserver(Observer* o)
{
observers.remove(o);
}
void Observable::notifyObservers(ObserverArg *oArg)
{
if (changed)
{
for (std::list<Observer*>::iterator it = observers.begin(); it != observers.end(); it++)
{
Observer* o = (Observer*)*it;
o->update(this, oArg);
}
changed = false;
}
}
void Observable::setChanged()
{
changed = true;
}
bool Observable::observerExists(Observer *o)
{
for (std::list<Observer*>::iterator it = observers.begin(); it != observers.end(); it++)
{
if (o == *it)
{
return true;
}
}
return false;
}
class ObserverArg {
public:
void *arg;
};
class Observer {
public:
virtual void update(Observable *o, ObserverArg *oArg);
};
void Observer::update(Observable* o, ObserverArg *oArg)
{
}
简单测试
///Test code
class DummySubject : public Observable
{
public:
DummySubject()
: state(false), dummyA(5), dummyB(10)
{
}
void measurementsChanged()
{
int a = 100;
ObserverArg *oArg = new ObserverArg();
oArg->arg = (void *)&a;
setChanged();
notifyObservers(oArg);
delete oArg;
}
void pollingState()
{
if (state)
{
measurementsChanged();
state = false;
}
}
int getDummyA()
{
return dummyA;
}
int getDummyB()
{
return dummyB;
}
void stateChange()
{
state = true;
}
private:
bool state;
int dummyA;
int dummyB;
};
class BorningObserver : public Observer
{
public:
virtual void update(Observable* o, ObserverArg *oArg)
{
DummySubject *ds = (DummySubject *)o;
std::cout << "I am a borning observer" << std::endl;
std::cout << "dummyA + dummyB = " << ds->getDummyA() + ds->getDummyB() << std::endl;
}
};
class ExcitedObserver : public Observer
{
public:
ExcitedObserver(int excitedFactor)
: excitedFactor(excitedFactor)
{
}
virtual void update(Observable* o, ObserverArg *oArg)
{
std::cout << "I am a excited observer with excited factor " << excitedFactor << "%" << std::endl;
}
public:
int excitedFactor;
};
int testObserverRoutine()
{
DummySubject subject;
Observer *o1 = new BorningObserver();
Observer *o2 = new ExcitedObserver(50);
subject.registerObserver(o1);
subject.registerObserver(o2);
subject.registerObserver(o1);
///state changed
subject.stateChange();
subject.pollingState();
subject.removeObserver(o1);
subject.stateChange();
subject.pollingState();
delete o1;
delete o2;
return 0;
}