Observer,观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并被自动更新。
http://blog.163.com/zhoumhan_0351/blog/static/39954227201043153542462
有两种方法,一种是推,另外一种是拉。所谓推是指每当subject有更新时,其会依次调用observer中的update函数,向observer发送关于更新的详细信息,通知他们自己的改变;而拉是指除最小通知外,subject什么也不发送,而之后由观察者显式地向目标访问细节。
1、推模式
class Subject;
class Observer{
public:
virtual ~Observer(){}
virtual void Update(Subject *theChangeSubject)=0;
protected:
Observer();
};
class Subject{
public:
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify();
protected:
Subject();
private:
list<Observer*> *_observers;
};
void Subject::Attach(Observer* o){
_observers->Append(o);
}
//...
void Subject::Notify(){
listIteraotr<Observer*> i(_observers);
for(i.first();!i.isdone();i.next()){
i.currentitem()->update(this);//推模式,有更新时,将全部信息通知一次
}//
}
class ConcreteSubject:public Subject{
//...
void GetState(){}//...
void SetState(){}//...
void NotifyAll(){
Notify();//通知
//...
}
}
class ConcreteObserver1:public Observer{
ConcreteObserver1(ConcreteSubject* s){
_subject=s;//注册
_subject->Attach(this);//注册
}
virtual ~ConcreteObserver1(){}
virtual void Update(Subject* theChangeSubject){
//...
if(theChangeSubject==_subject)
Drwa();
}
virtual void Draw(){
//...
}
private:
ConcreteSubject* _subject;
}
class ConcreteObserver2:public Observer{
ConcreteObserver2(ConcreteSubject* s){
_subject=s;//注册
_subject->Attach(this);//注册
}
virtual ~ConcreteObserver2(){}
virtual void Update(Subject* theChangeSubject){
//...
if(theChangeSubject==_subject)
Drwa();
}
virtual void Draw(){
//...
}
private:
ConcreteSubject* _subject;
}
ConcreteSubject* ConcreteSubjectIt=new ConcreteSubject;
ConcreteObserver1* ConcreteObserver1It=new ConcreteObserver1(ConcreteSubjectIt);
ConcreteObserver2* ConcreteObserver2It=new ConcreteObserver2(ConcreteSubjectIt);
2、拉模式
我们将更新操作定义在观察者中。
将更新操作Update定义在一个定时器中,每秒钟/或一定时间触发一次来获取新的状态。
class Subject;
class Observer{
public:
virtual ~Observer(){}
//virtual void Update(Subject *theChangeSubject)=0;
protected:
Observer();
};
class Subject{
public:
virtual void Attach(Observer*);
virtual void Detach(Observer*);
protected:
Subject();
private:
list<Observer*> *_observers;
};
void Subject::Attach(Observer* o){
_observers->Append(o);
}
class ConcreteSubject:public Subject{
//...
void GetState(){}
void SetState(){}
}
class ConcreteObserver1:public Observer{
ConcreteObserver1(ConcreteSubject* s){
_subject=s;//注册
_subject->Attach(this);
}
virtual ~ConcreteObserver1(){}
void Ontimer(){//每隔一定时间
if(theChangeSubject==_subject)
Drwa();
}
}//Ontimer
virtual void Draw(){
//...
}
private:
ConcreteSubject* _subject;
}
class ConcreteObserver2:public Observer{
ConcreteObserver2(ConcreteSubject* s){
_subject=s;//注册
_subject->Attach(this);
}
virtual ~ConcreteObserver2(){}
void OnTimer(){
if(theChangeSubject==_subject)
Drwa();
}
virtual void Draw(){
//...
}
private:
ConcreteSubject* _subject;
}
ConcreteSubject* ConcreteSubjectIt=new ConcreteSubject;
ConcreteObserver1* ConcreteObserver1It=new ConcreteObserver1(ConcreteSubjectIt);
ConcreteObserver2* ConcreteObserver2It=new ConcreteObserver2(ConcreteSubjectIt);