设计模式-观察者模式

观察者模式又称订阅-发布模式。指程序中有一个主题(subject),有若干个观察者(observer);当主题发生变动时,主题将通知订阅了该主题的观察者(调用观察者的updata方法)。程序可在运行时动态的添加或删除观察者。

讨论模型:
学校为主题,学生为观察者,学校将向学生发布三个数据。每次数据更新时,注册成为观察者的学生都会收到变化的数据。并可以在运行时,动态的添加删除观察者(学生)。

subject基类:

//subject.h
#ifndef _________Subject__
#define _________Subject__

#include <stdio.h>
#include "Observer.h"
class Subject{
public:
    virtual void registerObserver(Observer* observer)=0;//添加观察者
    virtual void removeObserver(Observer* observer)=0;//删除观察者
    virtual void notifyObservers()=0;//数据变动时subject调用此方法通知observer进行updata
};

#endif

observer基类

//observer.h
#ifndef _________Observer__
#define _________Observer__

#include <stdio.h>
#include "map"
#include "string"
class Observer{
public:
    virtual void updata(std::map<std::string, int> data)=0;//调用该方法更新数据,参数为map类型键值对,可根据实际情况修改或重载
};

#endif

继承自subject的school类

//school.h
#ifndef _________school__
#define _________school__

#include <stdio.h>
#include "Subject.h"
#include "Observer.h"
#include <random>
#include "vector"
#include "map"
class school : public Subject {
private:
    int data1;//三个数据
    int data2;
    int data3;
    std::vector<Observer*> Obs;//观察者向量
    std::map<std::string, int> data;//储存三组数据的map

public:
    school() = default;

    void getData(){
        data1 = random();//更新三组数据
        data2 = random();
        data3 = random();
        data["data1"] = data1;
        data["data2"] = data2;
        data["data3"] = data3;
        notifyObservers();//调用notifyObserves通知observes调用updata
    }


    void registerObserver(Observer* observer){
        Obs.push_back(observer);//将参数observer加入观察者列表
    }

    void removeObserver(Observer* observer){
        for (auto i = Obs.begin(); i!=Obs.end(); i++) {
            if (*i == observer) {
                Obs.erase(i);//在列表中删除指定的observer
            }
        }
    };

    void notifyObservers(){
        for (auto i = Obs.begin(); i!=Obs.end(); i++) {
            (*i)->updata(data);//通知所有observer进行updata
        }
    }
};
#endif

继承自observer的student类

//student.h
#ifndef _________student__
#define _________student__

#include <stdio.h>
#include "Observer.h"
class students : public Observer{
private:
    int data1;
    int data2;
    int data3;
    int studentNum;
public:
    students(int studentNum){
        this->studentNum = studentNum;
    }
    void updata(std::map<std::string, int> data){
        data1 = data["data1"];
        data2 = data["data2"];
        data3 = data["data3"];
        show();
    }
    void show(){
        printf("student number:%d data1:%d,data2:%d,data3:%d\n",studentNum,data1,data2,data3);
    }
};
#endif

主函数:

#include <iostream>
#include "school.h"
#include "student.h"

int main(int argc, const char * argv[]) {
    auto sch  = new school();
    auto stu1 = new students(1);
    auto stu2 = new students(2);
    auto stu3 = new students(3);

    sch->registerObserver(stu1);
    sch->registerObserver(stu2);
    sch->registerObserver(stu3);

    sch->getData();

    sch->removeObserver(stu2);

    sch->getData();

    sch->removeObserver(stu1);

    sch->getData();

    sch->registerObserver(stu1);

    sch->getData();

    return 0;
}

输出结果

student number:1    data1:1804289383,data2:846930886,data3:1681692777
student number:2    data1:1804289383,data2:846930886,data3:1681692777
student number:3    data1:1804289383,data2:846930886,data3:1681692777
student number:1    data1:1714636915,data2:1957747793,data3:424238335
student number:3    data1:1714636915,data2:1957747793,data3:424238335
student number:3    data1:719885386,data2:1649760492,data3:596516649
student number:3    data1:1189641421,data2:1025202362,data3:1350490027
student number:1    data1:1189641421,data2:1025202362,data3:1350490027

你可能感兴趣的:(设计模式)