C++观察者模式

ops/2024/9/23 12:28:57/
一、定义

观察者(Observer)模式 定义如下:
是一种对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

二、观察者模式组成:
  • 抽象目标角色(Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。
  • 抽象观察者角色(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
  • 具体目标角色(Concrete Subject):当它的状态发生改变时, 向它的各个观察者发出通知。可以维护一个指向Concrete Subject 对象的指针,通过这个对象在构造函数注册,在析构函数删除
  • 具体观察者角色(Concrete Observer):实现Observer 的更新接口以使自身状态与目标的状态保持一致。在本角色内也
三、 总结

1.观察者模式 主要解决了什么问题?
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

2.观察者模式 何时使用?
一个对象的状态发生改变,所有的依赖对象都将得到通知,进行广播通知。

3、观察者模式 的优缺点
【优点】

  • 观察者和被观察者是抽象耦合的。
  • 建立一套触发机制。

【缺点】

  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
四、 代码示例:
#include <iostream>
#include <vector>
#include <algorithm>// 抽象观察者角色
class Subject;class Observer {
public:virtual ~Observer() {if (subject) {subject->detach(this);}}virtual void update() = 0;protected:Observer(Subject* sub) : subject(sub) {subject->attach(this);}Subject* subject;
};// 抽象目标角色
class Subject {
public:virtual ~Subject() {}void attach(Observer* observer) {observers.push_back(observer);}void detach(Observer* observer) {observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());}void notify() {for (Observer* observer : observers) {observer->update();}}private:std::vector<Observer*> observers;
};// 具体目标角色
class ConcreteSubject : public Subject {
public:void setState(int state) {this->state = state;notify();}int getState() const {return state;}private:int state;
};// 具体观察者角色
class ConcreteObserver : public Observer {
public:ConcreteObserver(ConcreteSubject* sub) : Observer(sub), subject(sub) {}void update() override {std::cout << "Observer: Subject's state is " << subject->getState() << std::endl;}private:ConcreteSubject* subject;
};int main() {ConcreteSubject subject;ConcreteObserver observer1(&subject);ConcreteObserver observer2(&subject);subject.setState(1);subject.setState(2);return 0;
}

http://www.ppmy.cn/ops/53166.html

相关文章

Redis 内存碎片是什么?如何清理?

Redis 内存碎片相关的问题在得物、美团、阿里、字节、携程等公司的后端面试中都曾出现过&#xff0c;还是建议认真准备一下。即使不是准备面试&#xff0c;日常开发也是能够用到的&#xff01; 什么是内存碎片? 你可以将内存碎片简单地理解为那些不可用的空闲内存。 举个例子&…

Java学习:第九章接口

★ 抽象方法和抽象类 ★ 接口 ★ 策略设计模式和适配器设计模式 抽象类和抽象方法&#xff1a; 1、 抽象方法 ★ 使用关键字 abstract修饰的方法称为抽象方法, 仅有方法声明没有方法体。 2、 抽象类 ★包含抽象方法的类称为抽象类&#xff0c;必须也用abstrac…

思科路由器密码恢复方法

1.密码恢复原理 Cisco路由器保存了几种不同的配置参数&#xff0c;并存放在不同的内存模块中。 Cisco系列路由器的内存有&#xff1a;ROM&#xff0c;闪存&#xff08;Flashmemory&#xff09;,RAM&#xff0c;不可变RAM和动态内存&#xff08;DRAM&#xff09;等5种。 一般情况…

批量打造怀旧风情:视频批量剪辑将现代视频打造成怀旧经典老视频效果

在繁忙的现代生活中&#xff0c;我们时常怀念那些旧时光&#xff0c;那些充满岁月痕迹的老电影片段。它们不仅记录了一个时代的风貌&#xff0c;更承载了无数人的情感与记忆。你是否想过&#xff0c;将现代的视频素材打造成这种怀旧经典的老视频效果&#xff0c;让每一帧都充满…

基于C++标准库实现定时器类

基于C标准库实现定时器类 定时器类是多线程编程中经常设计到的工具类 简单的定时器原理其实很简单&#xff08;是不是有点GNU is not unix的味道;&#xff09;&#xff1a; 创建一个新线程在那个线程里等待等待指定时长后做任务 python标准库中就有这么一个定时器类&#xf…

【FFmpeg】AVFrame结构体

【FFmpeg】AVFrame结构体 1.AVFrame结构体的定义enum AVPictureType pict_typeAVFrameSideData **side_data 参考&#xff1a; FFMPEG结构体分析&#xff1a;AVFrame 示例工程&#xff1a; 【FFmpeg】调用ffmpeg库实现264软编 【FFmpeg】调用ffmpeg库实现264软解 【FFmpeg】调…

LeetCode刷题(739/496/503)/华为od转盘寿司-单调栈

739.每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例 1: 输…

Flask初识

Flask初识 一、概念说明 1. flask介绍 Flask 是一个轻量级的 Web 应用框架&#xff0c;基于 Werkzeug WSGI 工具包和 Jinja2 模板引擎。 核心特点 微型框架&#xff1a;Flask 被称为“微”框架&#xff0c;因为它在设计上保持了核心的简洁和轻量。易于扩展&#xff1a;Flask…