首页 > 其他分享 >设计模式——观察者模式

设计模式——观察者模式

时间:2024-10-09 18:48:13浏览次数:9  
标签:std Observer observer void 观察者 模式 observers 设计模式

在这里插入图片描述
哈喽,各位盆友们!我是你们亲爱的学徒小z,今天给大家分享的文章是设计模式的——观察者模式。

定义

  • 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

通用类图

image-20241008153610284

1.具体结构

  • Subject被观察者

    定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类 或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。

  • Observer观察者

    观察者接收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。

  • ConcreteSubject具体的被观察者

定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。

  • ConcreteObserver具体的观察者

每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑

2.具体代码

#include <iostream>
#include <vector>
#include <algorithm>

// 观察者接口
class Observer {
public:
    virtual ~Observer() {}
    virtual void update(const std::string& message) = 0;
};

// 被观察者接口
class Subject {
public:
    virtual ~Subject() {}
    virtual void subscribe(Observer* observer) = 0;
    virtual void unsubscribe(Observer* observer) = 0;
    virtual void notify(const std::string& message) = 0;
};

// 具体的观察者类
class ConcreteObserver : public Observer {
private:
    std::string name;
public:
    ConcreteObserver(const std::string& name) : name(name) {}
    void update(const std::string& message) override {
        std::cout << name << " received notification: " << message << std::endl;
    }
};

// 具体的被观察者类
class ConcreteSubject : public Subject {
private:
    std::vector<Observer*> observers;
public:
    void subscribe(Observer* observer) override {
        observers.push_back(observer);
    }

    void unsubscribe(Observer* observer) override {
        observers.erase(
            std::remove(observers.begin(), observers.end(), observer),
            observers.end());
    }

    void notify(const std::string& message) override {
        for (Observer* observer : observers) {
            observer->update(message);
        }
    }
};

int main() {
    // 创建被观察者
    ConcreteSubject subject;

    // 创建观察者
    ConcreteObserver observer1("Observer 1");
    ConcreteObserver observer2("Observer 2");

    // 订阅观察者
    subject.subscribe(&observer1);
    subject.subscribe(&observer2);

    // 发送通知
    subject.notify("Hello, Observers!");

    // 取消订阅观察者1
    subject.unsubscribe(&observer1);

    // 再次发送通知
    subject.notify("Second notification");

    return 0;
}

3.观察者模式的优点

  • 观察者与被观察者之间是抽象耦合

    如此设计,则不管是增加观察者还是被观察者都非常容易扩展

  • 建立一套触发机制

4.缺点

  • 需要考虑一下开发效率和运行效率的问题,一个被观察者,多个观察者,开发和调试就会比较复杂。如果是顺序执行,一个观察者卡壳,会影响整体效率,在这种情况下,一般采用异步方式。
  • 多级触发时的效率可能更不太好

5.使用场景

  • 关联行为场景。关联行为是可拆分的,而不是组合关系
  • 事件多级触发场景
  • 跨系统的消息交换场景,如消息队列的处理机制

注意事项

  • 个观察者可以有双重身份,既是观察者,也是被观察者,但是链一旦建立,这个逻辑就比较复杂,可维护性非常差,根据经验建议,在一个观察者模式中最多出现一个对象既是观察者也是被观察者,也就是说消息最多转发一次(传递两次)

  • 异步处理问题

    被观察者发生动作了,观察者要做出回应,如果观察者比较多,就用异步处理,要考虑线程安全和队列的问题

它和责任链模式的最大区别就是观察者广播链在传播的过程中消息是随时更改 的,它是由相邻的两个节点协商的消息结构;而责任链模式在消息传递过程中基本上保持消 息不可变,如果要改变,也只是在原有的消息上进行修正

项目中的实际用法

1.观察者和被观察者之间的消息沟通

被观察者状态改变会触发观察者的一个行为,同时会传递一个消息给观察者

2.观察者响应方式

如果观察者是一个比较复杂的逻辑,它要接受被观察者传递过来的 信息,同时还要对他们进行逻辑处理,在一个观察者多个被观察者的情况下,就需要考虑性能需求了。两个办法:

  • 多线程
  • 缓存技术

3.观察者尽量自己做主

被观察者的状态改变是否一定要通知观察者呢?不一定

一般这样做,对被观察者的业务逻辑 doSomething方法实现重载,如增加一个doSomething(boolean isNotifyObs)方法,决定是否通知观察者,而不是在消息到达观察者时才判断

标签:std,Observer,observer,void,观察者,模式,observers,设计模式
From: https://blog.csdn.net/m0_66825548/article/details/142762118

相关文章

  • 设计模式——门面模式 | 外观模式
    哈喽,各位盆友们!我是你们亲爱的学徒小z,今天给大家分享的文章是设计模式的——门面模式。文章目录定义通用类图1.通用结构2.优点3.缺点使用场景注意事项1.一个子系统可以有多个门面2.门面不参与子系统内的业务逻辑定义定义:要求一个子系统的外部与其内部的通信必须......
  • 【网络配置】聚合链路eNSP--静态 LACP 模式
            聚合链路(LinkAggregation),也称为链路捆绑、链路聚合组(LAG,LinkAggregationGroup)或以太网链路聚合,是一种将多个物理网络接口(例如以太网端口)组合成一个逻辑链路的技术。聚合链路的配置通常涉及以下两种模式:手工模式(StaticLAG):在这种模式下,网络管理员手动配置......
  • padding模式
    缘起在遇到AES和DES等分组加密算法时,需要明文满足一定的长度要求(分组的倍数),但是大多数情况下明文没法满足长度的苛刻要求,于是就要进行padding使传入的内容满足长度要求。Nopadding就是不填充,明文满足分组算法的长度要求,不需要再进行填充。PKCS5/PKCS7填充数据为填充字节的长......
  • HourlyEmployee 和SalariedEmployee 设计模式实现
    1.1IntroductionNote:Thisassignmentisabitdifferentfromtheprevioushomework,andasksyoutopracticewithJUnit5.Ensureyoureadtheinstructionscarefullyandsubmitwhatisrequired.Volunteerworkisadmirable,butmanypeopleenjoybeingpaid......
  • 我店平台模式:商家与消费者双向探索
    在当今这个数字化时代,消费者的购物体验与商家的经营模式正经历着前所未有的变革。而我店平台,作为这一变革的引领者,正通过一系列创新机制,为商家与消费者搭建起一座互利共赢的桥梁。其中,“金币商城”、“抵用券”、“积分奖励”等机制成为了我店平台上的亮点,不仅让消费者享受到了实......
  • 网络接入的镜像模式和串接模式
    网络接入的镜像模式和串接模式主要有以下特点: 一、镜像模式1. 工作原理 -镜像模式也称为端口镜像,是将网络中指定端口的数据流量复制一份到另一个监测端口,以便进行网络分析、故障排查和安全监控等。例如,将连接重要服务器的交换机端口流量镜像到一个用于网络监测的设备......
  • 我店生活模式功能分析
    一、平台概述“我店”由上海我店科技网络有限公司创立于2021年8月,作为一个本地生活服务平台,它致力于响应国家的环保政策,并运用绿色积分来促进经济活动,帮助实体店铺吸引客流。面对实体商业的挑战,“我店”平台凭借其独特的商业模式,为商户与顾客提供了新的合作与发展机遇。二、核......
  • 界面控件Kendo UI for jQuery 2024 Q3亮点 - 支持切换编辑模式
    随着最新的2024Q3版本,Progress使用户能够使用现成的页面模板和构建块更快地构建令人惊叹的应用程序,使您的Telerik和KendoUI开发体验更好。Telerik和KendoUI 2024Q3版本将焦点放在新推出的页面模板和构建块上,每个页面模板和构建块都预先配置了TelerikUIforBlazor、KendoU......
  • 【一步步开发AI运动小程序】二十、AI运动小程序如何适配相机全屏模式?
    引言受小程序camera组件预览和抽帧图像不一致的特性影响,一直未全功能支持全屏模式,详见本系列文件第四节小程序如何抽帧;随着插件在云上赛事、健身锻炼、AI体测、AR互动场景的深入应用,各开发者迫切的希望能在全屏模式下应用,以便获得更合理的UI布局和更佳的用户体验,经过我们的努力......
  • 大数据-158 Apache Kylin 安装配置详解 集群模式启动
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(已更完)Kudu(已更完)Druid(已更完)Kylin(正在更新…)章节内容上节......