设计模式—观察者模式与发布订阅

观察者设计模式

观察者设计模式(Observer Design Pattern)是一种常用的软件设计模式,它是一种行为型模式。该模式用于定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。

结构

观察者模式通常涉及以下几个角色:

  1. Subject(主题):主题是被观察的对象,它包含了需要被观察的状态。当主题状态发生变化时,它会通知所有的观察者对象。

  2. Observer(观察者):观察者是依赖于主题的对象,它们将在主题状态发生变化时得到通知,并进行相应的更新操作。

  3. ConcreteSubject(具体主题):具体主题是主题的具体实现,它维护了一组观察者对象,并在状态发生改变时通知它们。

  4. ConcreteObserver(具体观察者):具体观察者实现了观察者接口,在收到主题通知时执行特定的更新操作。

示例

以下是一个简单的观察者模式的示例,假设我们有一个主题(Subject)代表气象站,而观察者(Observer)是一组天气显示板,它们会在气象站更新数据时自动更新显示:

import java.util.ArrayList;
import java.util.List;

// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 观察者接口
interface Observer {
    void update(float temperature, float humidity, float pressure);
}

// 具体主题
class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() {
        observers = new ArrayList<>();
    }

    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }

    public void measurementsChanged() {
        notifyObservers();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}

// 具体观察者
class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;

    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }

    public void display() {
        System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
    }
}

// 测试
public class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        
        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();
        
        weatherData.registerObserver(currentDisplay);
        
        weatherData.setMeasurements(80, 65, 30.4f);
    }
}

发布订阅者模式

发布-订阅者模式(Publish-Subscribe Pattern)是一种软件设计模式,用于实现消息的发布和订阅机制,也被称为观察者模式的变体。在发布-订阅者模式中,消息的发布者(发布者)和消息的接收者(订阅者)之间没有直接的依赖关系,它们通过一个称为"消息代理"或"事件总线"的中介来进行通信。这种模式允许组件之间松耦合地通信,从而提高系统的可扩展性和灵活性。

结构

发布-订阅者模式通常包括以下几个关键部分:

  1. 发布者(Publisher):负责发布消息或事件到消息代理。

  2. 订阅者(Subscriber):注册对特定类型的消息或事件感兴趣,并在消息到达时执行相应的操作。

  3. 消息代理(Message Broker):作为发布者和订阅者之间的中介,负责管理消息的路由和传递。它维护了发布者和订阅者之间的关系,并在消息到达时将消息传递给所有订阅者。

示例

以下是一个简单的发布-订阅者模式的示例,假设我们有一个新闻发布系统,包括新闻发布者和新闻订阅者:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 消息代理
class MessageBroker {
    private Map<String, List<Subscriber>> topics = new HashMap<>();

    public void subscribe(String topic, Subscriber subscriber) {
        topics.computeIfAbsent(topic, k -> new ArrayList<>()).add(subscriber);
    }

    public void publish(String topic, String message) {
        List<Subscriber> subscribers = topics.get(topic);
        if (subscribers != null) {
            for (Subscriber subscriber : subscribers) {
                subscriber.receive(message);
            }
        }
    }
}

// 订阅者接口
interface Subscriber {
    void receive(String message);
}

// 新闻订阅者
class NewsSubscriber implements Subscriber {
    private String name;

    public NewsSubscriber(String name) {
        this.name = name;
    }

    public void receive(String message) {
        System.out.println(name + " received news: " + message);
    }
}

// 新闻发布者
class NewsPublisher {
    private MessageBroker messageBroker;

    public NewsPublisher(MessageBroker messageBroker) {
        this.messageBroker = messageBroker;
    }

    public void publishNews(String topic, String news) {
        messageBroker.publish(topic, news);
    }
}

// 测试
public class NewsSystem {
    public static void main(String[] args) {
        MessageBroker messageBroker = new MessageBroker();
        
        NewsPublisher publisher = new NewsPublisher(messageBroker);
        publisher.publishNews("sports", "New record set in 100m sprint!");
        publisher.publishNews("technology", "New smartphone announced!");
        
        NewsSubscriber subscriber1 = new NewsSubscriber("John");
        NewsSubscriber subscriber2 = new NewsSubscriber("Alice");
        
        messageBroker.subscribe("sports", subscriber1);
        messageBroker.subscribe("technology", subscriber2);
        
        publisher.publishNews("sports", "Team wins championship!");
    }
}

发布-订阅者模式在事件驱动的系统中非常有用,它可以使系统中的各个组件彼此解耦,并提供一种灵活的通信机制。

观察者vs发布订阅

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/479870.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OceanPen Art AI绘画系统 运营教程(二)AI视频AI创作PPT

在一个崇高的目标支持下&#xff0c;不停地工作&#xff0c;即使慢&#xff0c;也一定会获得成功。 —— 爱因斯坦 演示站点&#xff1a; ai.oceanpen.art 官方论坛&#xff1a; www.jingyuai.com 登陆后台 ppt密匙设置 导航菜单配置 Key池管理 二、前端显示 体验站点…

python食品安全信息管理系统flask-django-nodejs-php

。 食品安全信息管理系统是在安卓操作系统下的应用平台。为防止出现兼容性及稳定性问题&#xff0c;编辑器选择的是Hbuildex&#xff0c;安卓APP与后台服务端之间的数据存储主要通过MySQL。用户在使用应用时产生的数据通过 python等语言传递给数据库。通过此方式促进食品安全信…

2024年【化工自动化控制仪表】考试试卷及化工自动化控制仪表模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 化工自动化控制仪表考试试卷是安全生产模拟考试一点通总题库中生成的一套化工自动化控制仪表模拟考试题&#xff0c;安全生产模拟考试一点通上化工自动化控制仪表作业手机同步练习。2024年【化工自动化控制仪表】考试…

阿里云2核4G服务器租用价格和性能测评

阿里云2核4G服务器租用优惠价格&#xff0c;轻量2核4G服务器165元一年、u1服务器2核4G5M带宽199元一年、云服务器e实例30元3个月&#xff0c;活动链接 aliyunfuwuqi.com/go/aliyun 活动链接如下图&#xff1a; 阿里云2核4G服务器优惠价格 轻量应用服务器2核2G4M带宽、60GB高效…

Machine Vision Technology:Lecture8 Segmentation

Machine Vision Technology&#xff1a;Lecture8 Segmentation the goals of segmentationInspiration from psychologySegmentation as clusteringK-Means for segmentationMean shift clustering and segmentation均值偏移聚类和分割Segmentation by graph partitioningSegme…

一下想要邮寄很多快递,该怎么邮寄呢?

我们都知道淘宝网上开店的经常会邮寄很多快递&#xff0c;但是这么多快递不可能一下子拿到快递驿站去邮寄吧&#xff0c;但是快递员又不上门取件可怎么办呀&#xff0c;这可真是让人伤透了脑筋了&#xff0c; 我们都知道我们所在的区域一般都会有快递员来承揽我们所在区域的快递…

Penpad的Season 2 规则解读,其生态资产 $PDD LaunchPad 在即

Penpad 是 Scroll 上的 LauncPad 平台&#xff0c;该平台继承了 Scroll 底层的技术优势&#xff0c;并基于零知识证明技术&#xff0c;推出了系列功能包括账户抽象化、灵活的挖矿功能&#xff0c;并将在未来实现合规为 RWA 等资产登录 Scroll 生态构建基础。该平台被认为是绝大…

SCI一区 | Matlab实现PSO-TCN-BiGRU-Attention粒子群算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现PSO-TCN-BiGRU-Attention粒子群算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现PSO-TCN-BiGRU-Attention粒子群算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述…

_nodemon自动重启服务器

文章目录 1.安装模块 nodemon1.1安装方式2.jason文件里面可以存储自定义指令 由于每次修改代码都要重启服务器&#xff0c;所以我们希望有一种方式自动监视代码修改&#xff0c;自动启动服务器nodemon模块解决了这个问题 1.安装模块 nodemon 1.1安装方式 全局安装 npm i node…

企业必备的 Exchange 邮箱管理工具包:STELLAR TOOLKIT FOR EXCHANGE

天津鸿萌科贸发展有限公司是 Stellar 系列软件的授权代理商。 Stellar Toolkit for Exchange 工具包功能特性 将在线和离线EDB转换为PST Stellar Toolkit for Exchange 可以将邮箱从托管 Exchange 和脱机 EDB 导出为 PST 文件格式。该工具允许您根据需要连接单个或多个邮箱。…

CCF202309-2——坐标变换(其二)80分代码及思路

思路&#xff0c;还是暴力求解&#xff0c;直接对每一个操作进行遍历&#xff0c;最后结果保留三位小数&#xff0c;但是不知道为什么直接printf("%.3f",x)进行输出没有分&#xff0c;结果完全对得上&#xff0c;以下是80分提交代码&#xff0c;可能大的测试点没有通…

深度学习新篇章:PyTorch在遥感地物分类的革命性应用

我国高分辨率对地观测系统重大专项已全面启动&#xff0c;高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成&#xff0c;将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB&#xff0c;遥感大数据时…

深度学习语义分割开山鼻祖——FCN网络

FCN网络内容简介 FCN网络是第一个将深度学习应用于语义分割的网络&#xff0c;具有开创新和划时代的意义 FCN网络在2015年效果是非常惊艳的&#xff0c;准确率提高了10%左右&#xff0c;并且推理时间非常快 。下面是网络结构示意图和实验数据。 最后进行放大的预测图有21个通道…

IO网络通信

IO Bio&#xff1a; 同步阻塞&#xff0c;一个线程一次连接&#xff0c;基于字符流/字节流 Nio&#xff1a;同步非阻塞 一个线程多个连接&#xff0c;多个请求注册到多路复用selector上&#xff0c;多路复用器轮训连接 面向缓冲区&#xff0c; 从某通道读取数据到缓存区&…

文献速递:基于SAM的医学图像分割---nnSAM:即插即用的分割任何东西模型 模型提升了nnUNet性能

Title 题目 nnSAM: Plug-and-play Segment Anything Model Improves nnUNet Performance nnSAM&#xff1a;即插即用的分割任何东西模型 模型提升了nnUNet性能 01 文献速递介绍 在现代临床工作流中&#xff0c;医学图像的高效准确分割对于疾病诊断和预后、治疗计划和监控以…

InnoDB 缓存

本文主要聊InnoDB内存结构, 先来看下官网Mysql 8.0 InnoDB架构图 MySQL :: MySQL 8.0 Reference Manual :: 17.4 InnoDB Architecture 如上图所示,InnoDB内存主要包含Buffer Pool, Change Buffer, Log Buffer, Adaptive Hash Index Buffer Pool 其实 buffer pool 就是内存中的…

网络安全协议基本问题

Http和Https协议的端口号&#xff1a; Http&#xff1a;80 Https&#xff1a;443 网络监听&#xff1a; 网络监听是一种监视网络状态、数据流程以及网络上信息传输的工具&#xff0c;它可以将网络界面设定成监听模式&#xff0c;并且可以截获网络上所传输的信息。但是网络监…

Linux:权限的概念与理解

目录 1. Linux权限的概念 2. Linux权限管理 01.文件访问者的分类 02.文件类型和访问权限 03.文件权限值的表示方法 04. 文件访问权限的相关设置方法 3. 使用 sudo分配权限 4. 目录的权限 ---------- 权限 用户角色(具体的人) 文件权限属性 ---------- 1. Linux权限的…

大英赛-选择题 (持续更新中)

解题策略&#xff1a; 十五分钟内写完&#xff0c;单选&#xff1a; ABCD全部单项选择题 考的语法点弄清不懂得话 看《张道真语法》 不会的单词建议下载墨墨背单词 直接把不会的加入到要背的里面 知识点 2019年初赛&#xff1a; 2019年决赛&#xff1a;

QT信号和槽机制connect用法

信号与槽机制是绝对不可或缺且常用的&#xff0c;其中的参数一般都会比较简单&#xff0c;bool、int、QString之类的&#xff0c;但当我们想要传递相对比较复杂的参数&#xff0c;例如QVector<int>、QList<QString>&#xff0c;以及一些我们自定义的结构体时&#…