/************************************************************************/
/* 观察者模式 */
/************************************************************************/
#include <LIST>
#include <STRING>
#include <iostream>
using namespace std;
/*
编程要点:观察者接口要有一个更新自身状态的行为
被观察者(主题):要有一个存放与之相联系的观察者的链表,并有一个通知的行为,当被观察者的状态发生改变时,
它会通知所有与之相关联地具体观察者,即调用与之关联的观察者的Update方法
*/
class Subject;
//观察者接口(抽象)
class Observer{
public:
virtual ~Observer(){};
virtual void Update(Subject *concreteSubject){};//根据被观察者更新自身状态
};
//被观察者(主题)
class Subject
{
private:
list<Observer*> *obvs;
public:
//构造函数
Subject()
{
obvs = new list<Observer*>;
}
void Attach(Observer *observer)
{
obvs->push_front(observer);//向链表中加入一个待通知的观察者
}
void Detach(Observer *observer)
{
obvs->push_back(observer);//删除一个观察者
}
//通知每个观察者
void Notify()
{
list<Observer*>::iterator it;
it = obvs->begin();
for(;it!=obvs->end();it++){
(*it)->Update(this);//每个观察者被通知后更新自己的状态
}
}
public:
virtual char* getState(){return NULL;}
virtual void setState(){}
};
/*具体的主题*/
class ConcreteSubject : public Subject
{
private:
char *state;//被观察者的状态
public:
/*被观察者自身状态的设置与获取*/
char* getState()
{
return state;
}
void setState(char *state)
{
this->state = state;
}
};
//具体的观察者
class ConcreteObserverA : public Observer
{
private:
char *name;//名称
char *state;//状态
public:
ConcreteObserverA(char *name)
{
this->name = name;
}
void Update(Subject *concreteSubject)
{
state = concreteSubject->getState();//更新自身状态
cout<<"观察者:"<<name<<"的新状态是:"<<state<<endl;
}
};
void main()
{
//构造一个主题
ConcreteSubject *concreteSubject = new ConcreteSubject();
//让主题和观察者相联系
concreteSubject->Attach(new ConcreteObserverA("X"));
concreteSubject->Attach(new ConcreteObserverA("Y"));
//主题状态改变,并通知观察者
concreteSubject->setState("老师走了,大家可以玩了,哈哈");
concreteSubject->Notify();
printf("过了一段时间后........................\n");
//主题状态改变,再次通知观察者
concreteSubject->setState("老师来了,大家别说了");
concreteSubject->Notify();
}