C++观察者模式

前言

观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,在主题对象的状态发生变化时,会通知所有的观察者。

观察者模式角色如下:

  • 抽象主题(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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值