observer.h
#ifndef _OBSERVER_H_ #define _OBSERVER_H_ #include <string> using namespace std; typedef string State; class Subject; class Observer { public: virtual ~Observer(); virtual void Update(Subject* sub) = 0; virtual void PrintInfo() = 0; protected: Observer(); State m_st; }; class ConcreteObserverA:public Observer { public: ConcreteObserverA(Subject* sub); ~ConcreteObserverA(); void Update(Subject* sub); void PrintInfo(); protected: Subject* m_sub; }; class ConcreteObserverB:public Observer { public: ConcreteObserverB(Subject* sub); ~ConcreteObserverB(); void Update(Subject* sub); void PrintInfo(); private: Subject* m_sub; }; #endif
observer.cpp
#include <iostream> #include <string> #include <list> #include "subject.h" #include "observer.h" using namespace std; Observer::Observer() {} Observer::~Observer() {} // about ConcreteObserverA ConcreteObserverA::ConcreteObserverA(Subject* sub) { m_sub = sub; m_sub->Attach(this); } ConcreteObserverA::~ConcreteObserverA() { m_sub->Detach(this); } void ConcreteObserverA::Update(Subject* sub) { m_st = sub->GetState(); PrintInfo(); } void ConcreteObserverA::PrintInfo() { cout<<"ConcreteObserverA : "<<m_st<<endl; } // about ConcreteObserverB ConcreteObserverB::ConcreteObserverB(Subject* sub) { m_sub = sub; m_sub->Attach(this); } ConcreteObserverB::~ConcreteObserverB() { m_sub->Detach(this); } void ConcreteObserverB::Update(Subject* sub) { m_st = sub->GetState(); PrintInfo(); } void ConcreteObserverB::PrintInfo() { cout<<"ConcreteObserverB : "<<m_st<<endl; }
subject.h
#ifndef _SUBJECT_H_ #define _SUBJECT_H_ #include <string> #include <list> using namespace std; typedef string State; class Observer; class Subject { public: Subject(); virtual ~Subject(); virtual void Attach(Observer* obv); virtual void Detach(Observer* obv); virtual void Notify(); virtual void SetState(const State& st); virtual State GetState(); private: State m_st; list<Observer*> m_obvs; }; #endif
subject.cpp
#include <iostream> #include <string> #include <list> #include "subject.h" #include "observer.h" using namespace std; Subject::Subject() { m_st = "/0"; } Subject::~Subject() {} void Subject::Attach(Observer* obv) { m_obvs.push_back(obv); } void Subject::Detach(Observer* obv) { m_obvs.remove(obv); } void Subject::Notify() { list<Observer*>::iterator iter; for(iter = m_obvs.begin();iter != m_obvs.end();iter++) { (*iter)->Update(this); } } void Subject::SetState(const State& st) { m_st = st; } State Subject::GetState() { return m_st; }
main.cpp
#include <iostream> #include <string> #include "subject.h" #include "observer.h" using namespace std; int main() { Subject* sub = new Subject; Observer* ob1 = new ConcreteObserverA(sub); Observer* ob2 = new ConcreteObserverB(sub); sub->SetState("old"); sub->Notify(); sub->SetState("new"); sub->Notify(); delete ob1; delete ob2; delete sub; return 0; }
Observer模式是应用最多,影响最广的模式之一。我们熟知的MVC(Model/View/Control)就采用了Observer模式。MVC实现了业务逻辑和表示层的解耦。在MFC中,Doc/View(文档视图结构)提供了实现MVC模式的架构。在java阵容中,struts也采用了类似的思想。
当然,MVC 只是Observer 模式的一个实例。Observer 模式要解决的问题为:建立一个“一(Subject )对多(Observer)”的依赖关系,并且做到当 “一”变化的时候,依赖这个 “一” 的多也能够同步改变。最常见的一个例子就是:对同一组数据进行统计分析时候,我们希望 能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有的统计的显示都能够同时改变。Observer 模式就是解决了这一个问题。