设计模式之十六------Observer(观察者)

来源:互联网 发布:恐怖故事2剧情解析知乎 编辑:程序博客网 时间:2024/06/05 06:08

  问题:

当一个对象状态发生改变时,我们时常要通知其他对象,说明这个对象发生了改变,让其他对象做出反应;

解决方案:

观察者模式正是解决这种问题的不二之选,观察者模式完美的将观察者和被观察的对象分离开。被观察的发生改变时,观察者做出更新。观察者与被观察者之间不能是直接的类的调用,否则就会将两者耦合起来,使用接口或者纯虚类是解决问题的好办法;


#include <IOSTREAM>#include <VECTOR>#include <string>using namespace std;class Observer;class AbstractSubject{public:AbstractSubject(){}virtual ~AbstractSubject(){}virtual void SetState(const string &str)=0;virtual string& GetState()=0;virtual void Attach(Observer *observer)=0;virtual void Detach(Observer *observer)=0;virtual void Notify()=0;protected:vector<Observer*> observer;string state;};class Subject:public AbstractSubject{public:Subject();virtual ~Subject();virtual void SetState(const string &str);virtual string& GetState();virtual void Attach(Observer *observer);virtual void Detach(Observer *observer);virtual void Notify();};class Observer{public:virtual ~Observer(){}virtual void Update(AbstractSubject *sub)=0;virtual void PrintInfo(){}protected:Observer(){};AbstractSubject *subject;string state;};class ConcreateObserver1:public Observer{public:ConcreateObserver1(AbstractSubject *sub){this->subject=sub;this->subject->Attach(this);}virtual void Update(AbstractSubject *sub){state=sub->GetState();PrintInfo();}virtual void PrintInfo(){cout<<"ConcreateServer1:"<<state<<endl;}virtual ~ConcreateObserver1(){subject->Detach(this);}};class ConcreateObserver2:public Observer{public:ConcreateObserver2(AbstractSubject *sub){this->subject=sub;this->subject->Attach(this);}virtual void Update(AbstractSubject *sub){state=sub->GetState();PrintInfo();}virtual void PrintInfo(){cout<<"ConcreateServer2:"<<state<<endl;}virtual ~ConcreateObserver2(){subject->Detach(this);}};Subject::Subject(){}Subject::~Subject(){if (observer.size()>0){vector<Observer*>::iterator ite=observer.begin();while(ite!=observer.end()){delete (*ite);ite++;}}}void Subject::SetState(const string &str){state=str;}string& Subject::GetState(){return state;}void Subject::Attach(Observer *observer){this->observer.push_back(observer);}void Subject::Detach(Observer *observer){vector<Observer*>::iterator ite=this->observer.begin();while(ite!=this->observer.end()){if ((*ite)==observer){delete (*ite);return;}ite++;}}void Subject::Notify(){vector<Observer*>::iterator ite=observer.begin();while(ite!=observer.end()){(*ite)->Update(this);ite++;}}void main(){AbstractSubject *subject=new Subject;Observer *obs1=new ConcreateObserver1(subject);Observer *obs2=new ConcreateObserver2(subject);subject->SetState("good");subject->Notify();subject->SetState("bad");subject->Notify();}