【目的】1.稳定(减少外部依赖的开发量,只需要通过回调接受通知进行业务逻辑开发)
2.松耦合(为对象建立一种“通知依赖关系”,一个状态的改变,所有依赖的对象都会得到通知并自动更新)
3.可扩展(所有的想要建立“通知依赖关系”的业务都可以使用这一套框架进行开发)
【业务场景】在直播过程中需要依赖课程中的关键时间点来进行开发,通过Observer模式,提供关键时间点的服务,对依赖的对象进行通知,依赖的模块里通过回调进行业务开发。
【观察者实战】
写代码:
1.观察者纯虚类,让外部依赖的业务继承,实现回调方法,接受通知
class Observer : public QObject
{
Q_OBJECT
public:
Observer (QObject *parent = nullptr): QObject(parent) {}
virtual ~Observer () {}
public slots:
/**
* @brief update 根据被观察者的消息号,通知被观察者调用这个方法
* @param msg 业务消息号
*/
virtual void obsNotifyMsg(const QString &msg) = 0;
};
2.观察者管理基类,实现观察者的注册与反注册,消息的分发,观察者list管理
class Observerable : public QObject
{
Q_OBJECT
public:
explicit Observerable (QObject *parent = nullptr);
virtual ~Observerable ();
/**
* @brief attach 注册观察者
* @param msg 业务消息号
* @param object 观察对象
*/
bool attach(const QString &msg, QObject *object);
/**
* @brief detach 反注册观察者
* @param object 观察对象
*/
bool detach(QObject *object);
signals:
protected:
/**
* @brief setChange 派生类调用的通知方法
* @param msg 业务消息号
*/
bool setChange(const QString &msg);
private:
/**
* @brief notify 通知所有观察者
* @param msg 业务消息号
*/
bool notify(const QString &msg);
private:
QMultiHash<QString, QObject *> m_obsHash;
};
#define OBSERVE_NOTIFY_MSG ( "obsNotifyMsg" )
Observerable ::TeacherObserverable(QObject *parent) : QObject(parent)
{
}
Observerable ::~TeacherObserverable()
{
}
bool Observerable ::attach(const QString &msg, QObject *object)
{
if (object == nullptr || m_obsHash.contains(msg, object)) {
return false;
}
m_obsHash.insert(msg, object);
return true;
}
bool Observerable ::detach(QObject *object)
{
if (object == nullptr || m_obsHash.isEmpty()) {
return false;
}
QStringList keylist = m_obsHash.keys(object);
for (auto &elem : keylist) {
m_obsHash.remove(elem, object);
}
return true;
}
bool Observerable ::setChange(const QString &msg)
{
if (!notify(msg)) {
return false;
}
return true;
}
bool Observerable ::notify(const QString &msg)
{
if (!m_obsHash.contains(msg)) {
return false;
}
QList<QObject *> values = m_obsHash.values(msg);
for (auto &elem : values) {
if (elem) {
QMetaObject::invokeMethod(elem, OBSERVE_NOTIFY_MSG, Q_ARG(QString, msg));
}
}
return true;
}
3.时间服务类,派生自观察者管理基类
class TimeService : public Observerable
{
//自己做成单例,一般情况时间服务有一个即可
public:
TimeService();
~TimeService();
private:
bool initTimer();
private slots:
void onTimeout();//timeout的槽函数
private:
QTimer m_timer;
};
void TimeService::onTimeout()
{
setChange("101");
}
4.依赖时间服务的模块
class TestClass : public Observerable
{
Q_OBJECT
public:
explicit TestClass (QObject *parent = nullptr);
signals:
public slots:
virtual void obsNotifyMsg(const QString &msg);
}
void TestClass ::obsNotifyMsg(const QString &msg)
{
if (msg == "101") {
//TODO:
}
}
参考资料
【1】设计模式第五章 行为型模式 第七节Observer(观察者)
【2】https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/observer.html
【3】https://github.com/me115/design_patterns/blob/master/_static/Obeserver.jpg