《ASCE1885的设计模式》---观察者模式
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。这一模式镇中关键对象是目标(subject)和观察者(observer)。一个目标可以有任意数目的依赖于它的观察者。一旦目标的状态发生改变,所有观察者都得到通知。作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。这种交互又称为发布-订阅模式。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。
观察者模式的适用情况如下:
1)当一个抽象模型有两个方面,其中一个方面依赖于另一个方面;将这两者封装在独立的对象总以使它们可以各自独立地改变和复用;
2)当一个对象的改变需要同时改变其他对象,而不知道具体有多少个对象有待改变;
3)当一个对象必须通知其他对象,而它又不能假定其他对象是谁。即我们不希望这些对象是紧密耦合的。
观察者模式结构图如下:
观察者模式涉及到:
1)目标Subject:
目标知道它的观察者,可以有任意多个观察者观察同一个目标;提供注册和删除观察者对象的接口;
2)观察者Observer:
为那些在目标发生改变时需获得通知的对象定义一个更新接口;
3)具体目标ConcreteSubject:
将有关状态存入各ConcreteObserver对象;当它的状态发生改变时,向它的各个观察者发出通知;
4)具体观察者ConcreteObserver:
维护一个指向ConcreteSubject对象的引用;存储有关状态,这些状态应与目标的状态保持一致;实现Observer的更新接口以使自身状态与目标的状态保持一致;
实现:
观察者接口:
class Subject;
class Observer
{
public:
virtual ~Observer();
virtual void Update(Subject* m_subject) = 0;
protected:
Observer();
};
这种实现方式支持一个观察者有多个目标,当观察者观察多个目标时,作为参数传递给Update操作的目标让观察者可以判定是哪一个目标发生了改变。
目标接口:
class Subject
{
public:
virtual ~Subject();
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify();
protected:
Subject();
private:
std::list<Observer*> *_observers;
};
Subject::Subject()
{
//记得使用前初始化
_observers = new std::list<Observer*>;
}
void Subject::Attach(Observer* observer)
{
_observers->push_back(observer);
}
void Subject::Detach(Observer* observer)
{
if(observer != NULL)
_observers->remove(observer);
}
void Subject::Notify()
{
std::list<Observer*>::iterator it = _observers->begin();
while(it != _observers->end())
{
(*it)->Update(this);
++it;
}
}
下面的例子是从易做图上得来的:
#include <list>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
// The Abstract Observer
class ObserverBoardInte易做图ce
{
public:
virtual void update(float a,float b,float c) = 0;
};
// Abstract Inte易做图ce for Displays
class DisplayBoardInte易做图ce
{
public:
virtual void show() = 0;
};
// The Abstract Subject
class WeatherDataInte易做图ce
{
public:
virtual void registerob(ObserverBoardInte易做图ce* ob) = 0;
virtual void removeob(ObserverBoardInte易做图ce* ob) = 0;
virtual void notifyOb() = 0;
};
// The Concrete Subject
class ParaWeatherData: public WeatherDataInte易做图ce
{
public:
void SensorDataChange(float a,float b,float c)
{
m_humidity = a;
m_temperature = b;
m_pressure = c;
notifyOb();
}
void registerob(ObserverBoardInte易做图ce* ob)
{
m_obs.push_back(ob);
}
void removeob(ObserverBoardInte易做图ce* ob)
{
m_obs.remove(ob);
}
protected:
void notifyOb()
{
list<ObserverBoardInte易做图ce*>::iterator pos = m_obs.begin();
while (pos != m_obs.end())
{
((ObserverBoardInte易做图ce* )(*pos))->update(m_humidity,m_temperature,m_pressure);
(dynamic_cast<DisplayBoardInte易做图ce*>(*pos))->show();
++pos;
}
}
private:
float m_humidity;
float m_temperature;
float m_pressure;
list<ObserverBoardInte易做图ce* > m_obs;
};
// A Concrete Observer
class CurrentConditionBoard : public ObserverBoardInte易做图ce, public DisplayBoardInte易做图ce
{
public:
CurrentConditionBoard(WeatherDataInte易做图ce& a):m_data(a)
{
m_data.registerob(this);
}
void show()
{
cout<<"_____CurrentConditionBoard_____"<<endl;
cout<<"humidity: "<<m_h<<endl;
cout<<"temperature: "<<m_t<<endl;
cout<<"pressure: "<<m_p<<endl;
 
补充:软件开发 , C++ ,