观察者模式又叫做发布-订阅(Publish/Subscribe)模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
具体案例如下:
Makefile:
main:libObserver.so main.cpp
g++ main.cpp -omain -lObserver -L.
Subject.o:Subject.cpp
g++ -c -fpic Subject.cpp
Observer.o:Observer.cpp
g++ -c -fpic Observer.cpp
libObserver.so:Observer.o Subject.o
g++ -shared -olibObserver.so Observer.o Subject.o
.PHONY:clean
clean:
rm -rf *.o main *.so
编译命令make,然后export LD_LABRARY_PATH=.即可,运行./main结果如下:
ConcreteObserverB old _sub->GetState() old
ConcreteObserverA old _sub->GetState() old
ConcreteObserverB new _sub->GetState() new
ConcreteObserverA new _sub->GetState() new
详细代码如下:
Subject.h文件
//Subject.h
#ifndef _SUBJECT_H_
#define _SUBJECT_H_
#include <list>
#include <string>
using namespace std;
typedef string State;
class Observer;
class Subject
{
public:
virtual ~Subject();
virtual void Attach(Observer* obv);
virtual void Detach(Observer* obc);
virtual void Notify();
virtual void 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);
protected:
private:
State _st;
};
#endif//~_SUBJECT_H_
Subject.cpp代码如下:
#include "Subject.h"
#include "Observer.h"
#include <iostream>
#include <list>
using namespace std;
typedef string state;
Subject::Subject()
{
_obvs = new list<Observer*>;
}
Subject::~Subject()
{
delete _obvs;
}
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;
for (it = _obvs->begin(); it != _obvs->end(); it++)
{
(*it)->Update(this);
}
}
ConcreteSubject::ConcreteSubject()
{
_st = '\0';
}
ConcreteSubject::~ConcreteSubject()
{}
State ConcreteSubject::GetState()
{
return _st;
}
void ConcreteSubject::SetState(const State& st)
{
_st = st;
}
Observer.h代码如下:
//Observer.h
#ifndef _OBSERVER_H_
#define _OBSERVER_H_
#include "Subject.h"
#include <string>
using namespace std;
typedef string State;
class Observer
{
public:
virtual ~Observer();
virtual void Update(Subject* sub) = 0;
virtual void PrintInfo() = 0;
virtual State GetState();
protected:
Observer();
State _st;
private:
};
class ConcreteObserverA:public Observer
{
public:
virtual Subject* GetSubject();
ConcreteObserverA(Subject* sub);
virtual ~ConcreteObserverA();
void Update(Subject* sub);
void PrintInfo();
protected:
private:
Subject* _sub;
};
class ConcreteObserverB:public Observer
{
public:
virtual Subject* GetSubject();
ConcreteObserverB(Subject * sub);
virtual ~ConcreteObserverB();
void Update(Subject* sub);
void PrintInfo();
protected:
private:
Subject* _sub;
};
#endif//~_OBSERVER_H_
Observer.cpp代码如下:
//Observer.cpp
#include "Observer.h"
#include "Subject.h"
#include <iostream>
#include <string>
using namespace std;
Observer::Observer()
{
_st = '\0';
}
Observer::~Observer()
{
}
State Observer::GetState()
{
return _st;
}
ConcreteObserverA::ConcreteObserverA(Subject* sub)
{
_sub = sub;
_sub->Attach(this);
}
ConcreteObserverA::~ConcreteObserverA()
{
_sub->Detach(this);
}
Subject* ConcreteObserverA::GetSubject()
{
return _sub;
}
void ConcreteObserverA::PrintInfo()
{
cout<<"ConcreteObserverA "<<this->GetState()<<" _sub->GetState() "<<_sub->GetState()<<endl;
}
void ConcreteObserverA::Update(Subject* sub)
{
_st = sub->GetState();
PrintInfo();
}
ConcreteObserverB::ConcreteObserverB(Subject* sub)
{
_sub = sub;
_sub->Attach(this);
}
ConcreteObserverB::~ConcreteObserverB()
{
_sub->Detach(this);
}
Subject* ConcreteObserverB::GetSubject()
{
return _sub;
}
void ConcreteObserverB::PrintInfo()
{
cout<<"ConcreteObserverB "<<this->GetState()<<" _sub->GetState() "<<_sub->GetState()<<endl;
}
void ConcreteObserverB::Update(Subject* sub)
{
_st = sub->GetState();
PrintInfo();
}
main.cpp代码如下:
//main.cpp
#include "Subject.h"
#include "Observer.h"
#include<iostream>
using namespace std;
int main(int argc, char*argv[])
{
ConcreteSubject* sub = new ConcreteSubject();
Observer* o1 = new ConcreteObserverA(sub);
Observer* o2 = new ConcreteObserverB(sub);
sub->SetState("old");
sub->Notify();
sub->SetState("new");
sub->Notify();
delete o1;
delete o2;
delete sub;
return 0;
}