前言
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,在主题对象的状态发生变化时,会通知所有的观察者。
观察者模式角色如下:
- 抽象主题(Subject)角色:抽象主题角色提供维护一个观察者对象集合的操作方法,对集合的增加、删除等。
- 具体主题(ConcreteSubject)角色:将有关状态存入具体的观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发通知。具体主题角色负责实现抽象主题中的方法。
- 抽象观察者(Observer)角色:为具体观察者提供一个更新接口。
- 具体观察者(ConcreteObserver)角色:存储与主题相关的自洽状态,实现抽象观察者提供的更新接口。
场景有很多,就不举例了~~今天不想打字,除了代码基本拷贝
实现步骤
1、通常来说,第一步是定义两个内含纯虚函数的基类
- 观察者基类,且内含如下纯虚函数
更新消息的函数update(接受的内容),接受的内容是被观察者更新的内容。 - 被观察者基类,且内含如下纯虚函数
添加订阅者的函数,建立订阅者与自身的关系,即将订阅者加入到自身存放订阅者的容器中,后面使用的是set。
删除订阅者的函数,即从容器中去除指定订阅者。
更新内容的函数,即更新自身的消息,并逐一调用容器中订阅者的update函数。(精髓所在)
2、第二步是,创建具体的被观察者和具体的观察者类,实现上述的纯虚函数。
3、主函数中的调用步骤为
- 创建具体的被观察者的一个实例
- 创建若干具体观察者的实例
- 调用被观察者的订阅函数,建立关系
- 更新被观察者的信息,从而借助这种模式订阅者可以自动获取本次更新的信息
- 资源释放
上代码
/*************************************************
<文件名称> IObserver.h
<概要说明> 抽象观察者
<详细说明>
<作 者> mcq
<时 间> 2019-09-26
<修 改>
**************************************************/
#ifndef IOBSERVER_H
#define IOBSERVER_H
class IObserver{
public:
virtual ~IObserver(){}
virtual void update(int iValue) = 0;
};
#endif // IOBSERVER_H
/*************************************************
<文件名称> ConcreteObserver.h
<概要说明> 创建具体观察者
<详细说明> 无
<作 者> mcq
<时 间> 2019-09-29
<修 改>
**************************************************/
#ifndef CONCRETEOBSERVER_H
#define CONCRETEOBSERVER_H
#include <QString>
#include <QDebug>
#include "iobserver.h"
class ConcreteObserver : public IObserver
{
public:
ConcreteObserver(QString strObj){
m_strObj = strObj;
}
void update(int iValue){
qDebug()<<"m_strObj:"<<m_strObj<<" "<<QString("%1").arg(iValue);
}
private:
QString m_strObj{""}; //观察者
};
#endif // CONCRETEOBSERVER_H
/*************************************************
<文件名称> ISubject.h
<概要说明> 抽象主题
<详细说明>
<作 者> mcq
<时 间> 2019-09-26
<修 改>
**************************************************/
#ifndef ISUBJECT_H
#define ISUBJECT_H
#include "iobserver.h"
class ISubject{
public:
virtual ~ISubject(){}
//注册观察者
virtual void attach(IObserver *obs) = 0;
//注销观察者
virtual void detach(IObserver *obs) = 0;
//通知观察者
virtual void notify() = 0;
};
#endif // ISUBJECT_H
/*************************************************
<文件名称> ConcreteSubject.h
<概要说明> 创建具体主题
<详细说明> 无
<作 者> mcq
<时 间> 2019-09-29
<修 改>
**************************************************/
#ifndef CONCRETESUBJECT_H
#define CONCRETESUBJECT_H
#include <QList>
#include "isubject.h"
class ConcreteSubject : public ISubject
{
public:
void setValue(const int& iValue){
m_iValue = iValue;
}
//注册观察者
void attach(IObserver *obs){
m_ObserverList.append(obs);
}
//注销观察者
void detach(IObserver *obs){
m_ObserverList.removeOne(obs);
}
//通知观察者
void notify(){
auto it = m_ObserverList.begin();
while(it != m_ObserverList.end()){
(*it)->update(m_iValue);
++it;
}
}
private:
int m_iValue{10};
QList<IObserver*> m_ObserverList;
};
#endif // CONCRETESUBJECT_H
#include <QCoreApplication>
#include "concreteobserver.h"
#include "concretesubject.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//创建主题、观察者
ConcreteSubject *pSubject = new ConcreteSubject();
ConcreteObserver *pObs1 = new ConcreteObserver("MMM");
ConcreteObserver *pObs2 = new ConcreteObserver("CCC");
ConcreteObserver *pObs3 = new ConcreteObserver("QQQ");
//注册观察者
pSubject->attach(pObs1);
pSubject->attach(pObs2);
pSubject->attach(pObs3);
//改变数值,并通知观察者
pSubject->setValue(15);
pSubject->notify();
//注销观察者2
pSubject->detach(pObs2);
//再改再通知
pSubject->setValue(100);
pSubject->notify();
//指针释放
delete pObs1;
pObs1 = nullptr;
delete pObs2;
pObs2 = nullptr;
delete pObs3;
pObs3 = nullptr;
return a.exec();
}
输出:
m_strObj: "MMM" "15"
m_strObj: "CCC" "15"
m_strObj: "QQQ" "15"
m_strObj: "MMM" "100"
m_strObj: "QQQ" "100"
参考文章:
https://blog.csdn.net/liang19890820/article/details/61925314
https://blog.csdn.net/weixin_44344462/article/details/93205226
https://www.cnblogs.com/yangjj08/p/10533250.html