北京期刊网站建设,网站建设教程在线观看,中关村在线app下载,宿迁房产网安居客观察者模式#xff1a;
定义对象间的一种一对多#xff08;变化#xff09;的依赖关系#xff0c;以便当一个 对象(Subject)的状态发生改变时#xff0c;所有依赖于它的对象都 得到通知并自动更新
动机#xff1a;
在软件构建过程中#xff0c;我们需要为某些对象建立…观察者模式
定义对象间的一种一对多变化的依赖关系以便当一个 对象(Subject)的状态发生改变时所有依赖于它的对象都 得到通知并自动更新
动机
在软件构建过程中我们需要为某些对象建立一种“通知依赖关系”——一个对象目标对象的状态发生改变所有的依赖对象观察者对象都将得到通知。如果这样的依赖关系过于紧密 将使软件不能很好地抵御变化。
使用面向对象技术可以将这种依赖关系弱化并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合
总结
使用面向对象的抽象Observer模式使得我们可以独立地改变目标与观察者从而使二者之间的依赖关系达致松耦合。目标发送通知时无需指定观察者通知可以携带通知信息作为参数会自动传播。观察者自己决定是否需要订阅通知目标对象对此一无所知。Observer模式是基于事件的UI框架中非常常用的设计模式也是 MVC模式的一个重要组成部分。
实践案例
假如现有有一个业务场景我们需要写一个视频检测器该检测器会使用图像分割模型对输入的视频流进行检测如果监测到画面有人那么需要做针对人的具体操作比如将人框出来比如将人截取出来如果检测到画面中有汽车也会做具体操作比如将汽车涂为红色等等。 这样一个业务场景普通的写法我们很容易想到读取视频流然后对每一帧图像检测然后写if else if 检测到人 {…} else if 检测到汽车 {…} else if 检测到天空 {…} 这样的实现方式可以满足需求但是并不满足我们的设计原则 这是一个紧耦合的做法你的检测器要依赖于其他的视频操作类不符合我们的依赖倒置原则 我们可以将操作类抽象成一个接口然后再需要操作的时候调用接口。这样就解决了这个问题 不过还有一点在这个业务场景中操作类有不同的操作也就是说需要多个操作 因为我们进一步抽象 我们写一个操作基类然后再写多个操作类1操作类2都继承基类 到这一步其实观察者模型就出来了
观察者模型 我们可以把视频看作一个被观察者检测到的结果人、汽车、树木等这些相当于信息通知给谁通知呢给那些具体的操作类通知所以我们可以把对人操作的类、对汽车操作的类这些看作观察者。 被观察者将消息发送给观察者观察者根据消息来做不同的操作多态 并且在这个过程中支持观察者自主选择是否订阅消息。
代码实现以及注释
#include string
#include iostream
#include list
using namespace std;class Observer {// 抽象类接口
public:virtual void handleVideo(string detectInfo) 0;virtual ~Observer() {}
};class Observer1 : public Observer {
public:virtual void handleVideo(string detectInfo) {cout 截取人 endl;}
};class Observer2 : public Observer {
public:virtual void handleVideo(string detectInfo) {cout 截取汽车 endl;}
};class VideoDetecter {string m_filePath;string m_fileName;listObserver* m_observerList; // 抽象通知机制支持多个观察者public:VideoDetecter(string filePath, string fileName) {m_filePath filePath;m_fileName fileName;}void detect() {//1.读取视频流cout 读取视频流 m_filePath m_fileName endl;//2.循环每一帧处理int frameNum 10;for (int i 0; i frameNum; i) {//假设对第i帧图像处理得到识别结果 结果记作 detectInfostring detectInfo 识别结果;sendNotify(detectInfo);//发送通知}}void addObserver(Observer* observer) { //添加观察者m_observerList.push_back(observer);}void removeObserver(Observer* observer) { //移除观察者m_observerList.remove(observer);}
protected:virtual void sendNotify(string detectInfo) {listObserver*::iterator itor m_observerList.begin();while (itor ! m_observerList.end()) {(*itor)-handleVideo(detectInfo); //不同观察者对通知做出响应itor;}}
};int main() {string filePath /root/home/videoPath/;string fileName 001.mp4;Observer* observer;VideoDetecter detecter(filePath, fileName);Observer1 ob1;Observer2 ob2;detecter.addObserver(ob1);detecter.addObserver(ob2);detecter.detect();detecter.removeObserver(ob1);detecter.removeObserver(ob2);//detecter.detect();}