Observer模式是开发中,使用比较多的模式之一.Observer模式叫做观察者模式,它定义了一种一对多的依赖模式,让多个观察者同时监听某一对象状态,当这个对象状态发生变化时,这些观察者都得到通知.
下图即为Observer模式的类图:
实现如下: //Subject.h
//Subject.h #ifndef _SUBJECT_H_ #define _SUBJECT_H_ #include <string> #include <boost/ptr_container/ptr_container.hpp> typedef std::string State; class Observer; class Subject { public: virtual ~Subject(); virtual void Attach(Observer* obv); virtual void Detach(Observer* obv); virtual void Notify(); virtual void SetState(const State& st) = 0; virtual State GetState() = 0; protected: Subject(); private: boost::ptr_vector<Observer> obvs_; }; class ConcreteSubject : public Subject { public: ConcreteSubject(); ~ConcreteSubject(); State GetState(); void SetState(const State& st); private: State st_; }; #endif//Subject.cpp
//Subject.cpp #include "Subject.h" #include "Observer.h" #include <iostream> Subject::Subject() { } Subject::~Subject() { } void Subject::Attach(Observer* obv) { obvs_.push_back(obv); } void Subject::Detach(Observer* obv) { for(boost::ptr_vector<Observer>::iterator iter=obvs_.begin(); iter!=obvs_.end(); ++iter) { if(obv==&(*iter)) { obvs_.erase(iter);//dead loop???? break; } } return ; } void Subject::Notify() { for(boost::ptr_vector<Observer>::iterator iter=obvs_.begin(); iter!=obvs_.end(); ++iter) { iter->Update(this); } } ConcreteSubject::ConcreteSubject() { st_='\0'; } ConcreteSubject::~ConcreteSubject() { } void ConcreteSubject::SetState(const State& st) { st_=st; } State ConcreteSubject::GetState() { return st_; }//Observer.h
#ifndef _OBSERVER_H_ #define _OBSERVER_H_ #include "Subject.h" #include <string> typedef std::string State; class Observer { public: virtual ~Observer(); virtual void Update(Subject* sub)=0; virtual void PrintInfo()=0; protected: Observer(); State st_; }; class ConcreteObserverA:public Observer { public: virtual ~ConcreteObserverA(); ConcreteObserverA(Subject* sub); virtual Subject* GetSubject(); void Update(Subject* sub); void PrintInfo(); private: Subject* sub_; }; class ConcreteObserverB:public Observer { public: virtual ~ConcreteObserverB(); ConcreteObserverB(Subject* sub); virtual Subject* GetSubject(); void Update(Subject* sub); void PrintInfo(); private: Subject* sub_; }; #endif //_OBSERVER_H_//Observer.cpp
//Observer.cpp #include "Observer.h" #include "Subject.h" #include <iostream> #include <string> Observer::Observer() { st_='\0'; } Observer::~Observer() {} ConcreteObserverA::ConcreteObserverA(Subject* sub) { sub_=sub; sub_->Attach(this); } ConcreteObserverA::~ConcreteObserverA() { sub_->Detach(this); //if(sub_!=0) //delete sub_; } Subject* ConcreteObserverA::GetSubject() { return sub_; } void ConcreteObserverA::PrintInfo() { std::cout<<"ConcreteObserverA observer "<<st_<<std::endl; } void ConcreteObserverA::Update(Subject* sub) { st_=sub->GetState(); PrintInfo(); } ConcreteObserverB::ConcreteObserverB(Subject* sub) { sub_=sub; sub_->Attach(this); } ConcreteObserverB::~ConcreteObserverB() { sub_->Detach(this); //if(sub_!=0) //delete sub_; } Subject* ConcreteObserverB::GetSubject() { return sub_; } void ConcreteObserverB::PrintInfo() { std::cout<<"ConcreteObserverB observer "<<st_<<std::endl; } void ConcreteObserverB::Update(Subject* sub) { st_=sub->GetState(); PrintInfo(); }//main.cpp
#include "Subject.h" #include "Observer.h" int main() { ConcreteSubject* sub=new ConcreteSubject(); Observer* o1=new ConcreteObserverA(sub); Observer* o2=new ConcreteObserverB(sub); sub->SetState("old"); sub->Notify(); sub->Detach(o1); sub->SetState("new"); sub->Notify(); return 0; }