//Subject.h #include<list> #include<string> usingnamespace std;
typedef string State; class Observer; class Subject {
public:
virtual~Subject();
virtualvoid Attach(Observer* obv);
virtualvoid Detach(Observer* obv);
virtualvoid Notify();
virtualvoid SetState(const State& st)= 0;
virtual State GetState()= 0;
protected:
Subject();
private:
list<Observer*>* _obvs; };
class ConcreteSubject:public Subject {
public:
ConcreteSubject();
~ConcreteSubject();
State GetState();
void SetState(const State& st);
private:
State _st; }; |
//Subject.cpp #include"Subject.h" #include"Observer.h" #include<iostream> #include<list> usingnamespace std;
typedef string state;
Subject::Subject() { //在模板的使用之前一定要 new,创建 _obvs = new list<Observer*>; }
Subject::~Subject() {
}
void Subject::Attach(Observer* obv) { _obvs->push_front(obv); }
void Subject::Detach(Observer* obv) { if (obv!= NULL) _obvs->remove(obv); }
void Subject::Notify() { list<Observer*>::iterator it; it = _obvs->begin(); for (;it!= _obvs->end();it++) { //关于模板和 iterator的用法 (*it)->Update(this); } }
ConcreteSubject::ConcreteSubject() { _st = '\0'; }
ConcreteSubject::~ConcreteSubject() {
} State ConcreteSubject::GetState() { return _st; }
void ConcreteSubject::SetState(const State& st) { _st = st; } |
//Observer.h #include"Subject.h" #include<string> usingnamespace std;
typedef string State;
class Observer { public:
virtual~Observer();
virtualvoid Update(Subject* sub)= 0;
virtualvoid PrintInfo() = 0;
protected:
Observer();
State _st; };
class ConcreteObserverA:public Observer { public:
virtual Subject* GetSubject();
ConcreteObserverA(Subject* sub);
virtual~ConcreteObserverA();
//传入 Subject作为参数,这样可以让一个View 属于多个的 Subject 。 void Update(Subject* sub);
void PrintInfo();
private:
Subject* _sub; };
class ConcreteObserverB:public Observer { public:
virtual Subject* GetSubject();
ConcreteObserverB(Subject* sub);
virtual~ConcreteObserverB();
//传入 Subject作为参数,这样可以让一个View 属于多个的 Subject。
void Update(Subject* sub);
void PrintInfo();
private:
Subject* _sub; }; |
//Observer.cpp #include"Observer.h" #include"Subject.h" #include<iostream> #include<string> usingnamespace std;
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() { cout<<"ConcreteObserverA observer..."<<_sub->GetState()<<endl; }
Void ConcreteObserverA::Update(Subject* sub) { _st = sub->GetState(); PrintInfo(); }
ConcreteObserverB::ConcreteObserverB(Subject* sub) { _sub = sub; _sub->Attach(this); } |
#include"Subject.h" #include"Observer.h" #include<iostream> usingnamespace std;
int main(int argc,char* argv[]) { ConcreteSubject* sub=newConcreteSubject(); Observer* o1=new ConcreteObserverA(sub); Observer* o2=new ConcreteObserverB(sub);
sub->SetState("old"); sub->Notify(); sub->SetState("new");// 也可以由Observer调用 sub->Notify();
return0; } |
在 Observer模式的实现中,Subject维护一个 list作为存储其所有观察者的容器。每当
调用Notify操作就遍历list中的Observer对象,并广播通知改变状态(调用Observer的Update操作)。目标的状态 state可以由 Subject自己改变(示例),也可以由 Observer的某个操作引起 state的改变(可调用Subject的 SetState操作)。Notify操作可以由 Subject目标主动广播(示例),也可以由 Observer观察者来调用(因为 Observer维护一个指向Subject的指针)。
运行示例程序,可以看到当 Subject处于状态“old”时候,依赖于它的两个观察者都显
示“old”,当目标状态改变为“new”的时候,依赖于它的两个观察者也都改变为“new”。
大型系统开发过程中要用到的模式之一。
除了 MFC、 Struts提供了 MVC 的实现框架,在 Java语言中还提供了专门的接口实现 Observer模式:通过专门的类 Observable及 Observer接口来实现 MVC编程模式,其 UML图可以表示为:
Java中实现 MVC的 UML图。
这里的 Observer就是观察者,Observable则充当目标 Subject的角色。
Observer模式也称为发布-订阅(publish-subscribe),目标就是通知的发布者,观察者则是通知的订阅者(接受通知)。