一对多关系
松耦合
《Head First设计模式》p38
现在有三个使用天气数据的布告板。
布告板1,布告板2,布告板3
错误示范:
cpp
#ifndef WEATHERDATA_H
#define WEATHERDATA_H
class WeatherData
{
public:
WeatherData();
/**
* @brief getTemperature 得到温度
* @return
*/
double getTemperature()
{
return 1;
}
/**
* @brief getHumidity 得到湿度
* @return
*/
double getHumidity()
{
return 1;
}
/**
* @brief getPressure 得到气压
* @return
*/
double getPressure()
{
return 1;
}
/**
* @brief measurementschanged 一旦气象测量更新,此方法会被调用
*/
void measurementschanged()
{
//获取温度,湿度,气压
//更新布告板1
//更新布告板2
//更新布告板3
}
};
#endif // WEATHERDATA_H
针对具体实现编程,会导致我们以后在增加或删除布告板时必须修改该部分代码。
观察者模式
主题(subject)
观察者(observer)
主题对象管理某些数据
当主题内的数据改变,会通知观察者
观察者已经订阅主题以便在主题数据改变时能收到更新。
观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
cpp
#ifndef SUBJECT_H
#define SUBJECT_H
#include "observer.h"
/**
* @brief The Subject class 抽象的主题类
*/
class Subject
{
public:
Subject();
/**
* @brief registerObserver 注册观察者
*/
virtual void registerObserver(Observer * o)
{
}
/**
* @brief removeObserver 移除观察者
*/
virtual void removeObserver(Observer * o)
{
}
/**
* @brief notifyObservers 通知观察者们
*/
virtual void notifyObservers()
{
}
};
#endif // SUBJECT_H
cpp
#ifndef OBSERVER_H
#define OBSERVER_H
/**
* @brief The Observer class 抽象的观察者类
*/
class Observer
{
public:
Observer();
/**
* @brief update 当主题状态改变时,update()被调用
*/
void update();
};
#endif // OBSERVER_H
设计原则:
为了交互对象之间的松耦合设计而努力。
这样可以建立有弹性的OO系统,能够应对变化。
cpp
#ifndef WEATHERDATA_H
#define WEATHERDATA_H
#include "subject.h"
#include <QHash>
class WeatherData : public Subject
{
public:
WeatherData();
/**
* @brief getTemperature 得到温度
* @return
*/
double getTemperature()
{
return 1;
}
/**
* @brief getHumidity 得到湿度
* @return
*/
double getHumidity()
{
return 1;
}
/**
* @brief getPressure 得到气压
* @return
*/
double getPressure()
{
return 1;
}
/**
* @brief measurementschanged 一旦气象测量更新,此方法会被调用
*/
void measurementschanged()
{
//获取温度,湿度,气压
//通知观察者
notifyObservers();
}
virtual void registerObserver(Observer * o)
{
mObservers.insert(o);
}
virtual void removeObserver(Observer * o)
{
mObservers.removeOne(o)
}
virtual void notifyObservers()
{
foreach (auto var, mObservers) {
var->update();
}
}
private:
QList<Observer*> mObservers;
};
#endif // WEATHERDATA_H
采取观察者模式:主题的数据安全性有所保障。
可以从被观察者处推或拉数据。