【观察者模式】 ——每天一点小知识

在这里插入图片描述

                                                                                       💧 观察者模式 \color{#FF1493}{观察者模式} 观察者模式💧          


🌷 仰望天空,妳我亦是行人.✨
🦄 个人主页——微风撞见云的博客🎐
🐳 《数据结构与算法》专栏的文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺
💧 《Java学习笔记》专栏的文章是本人在Java学习中总结的一些知识点~ 💐
🥣 《每天一点小知识》专栏的文章可以丰富你的知识库,滴水成河~ 🌊
🪁 希望本文能够给读者带来一定的帮助~🌸文章粗浅,敬请批评指正!🐥


文章目录

  • 🐳设计模式之观察者模式
    • 引言
    • 观察者模式的概念和思想
    • 应用场景
    • 实现方式
      • 使用接口
      • 使用 Java 内置的观察者模式
    • 使用观察者模式
    • 总结
  • 🐳结语


🐳设计模式之观察者模式

引言

设计模式是软件开发中重要的概念之一。观察者模式是设计模式中的一种,它用于定义对象之间的一对多依赖关系,当一个对象的状态发生改变时,其所有依赖者都会得到通知并自动更新。在本文中,我们将深入探讨观察者模式的概念和思想,并介绍观察者模式的应用场景以及常见的代码实现方式。


观察者模式的概念和思想

  💧观察者模式是一种行为型设计模式,它建立了一种对象之间的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会得到通知并自动更新。

  💧观察者模式的核心思想是将观察者和被观察者解耦,使得它们可以独立变化。被观察者维护一个观察者列表,并提供注册、注销和通知观察者的方法。观察者通过注册到被观察者上,实现对被观察者状态变化的监听。

观察者模式的应用场景以及常见的代码实现方式 ↓

应用场景

  💧观察者模式通常在以下场景中使用:

  • 当一个对象的状态变化需要通知其他对象,并且不希望与被通知的对象之间产生紧耦合关系时。
  • 当一个对象的改变需要同时改变其他对象,并且不知道有多少对象需要改变时。
  • 当一个对象需要将自己的改变通知给一组对象

实现方式

  💧观察者模式有多种实现方式,其中最常见的方式包括使用接口使用 Java 内置的观察者模式实现。

使用接口

  💧首先,我们定义一个被观察者接口 Subject 和一个观察者接口 Observer

public interface Subject {
    void registerObserver(Observer observer);
    void unregisterObserver(Observer observer);
    void notifyObservers();
}

public interface Observer {
    void update();
}

在上述代码中,Subject 接口定义了注册观察者、注销观察者和通知观察者的方法。Observer 接口定义了观察者的 update() 方法,用于接收被观察者的通知。

  💧接下来,我们实现具体的被观察者类 ConcreteSubjectConcreteObserver

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private int state;

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

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

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }
}

public class ConcreteObserver implements Observer {
    private Subject subject;

    public ConcreteObserver(Subject subject) {
        this.subject = subject;
        subject.registerObserver(this);
    }

    public void update() {
        int state = subject.getState();
        // 处理被观察者状态变化的逻辑
    }
}

在上述代码中,ConcreteSubject 类实现了 Subject 接口,它维护了一个观察者列表并实现了注册、注销和通知观察者的方法。当 ConcreteSubject 的状态发生变化时,它会调用 notifyObservers() 方法通知所有观察者。

ConcreteObserver 类实现了 Observer 接口,它在构造函数中注册到被观察者上,并实现了 update() 方法来处理被观察者状态变化的逻辑。

使用 Java 内置的观察者模式

  💧Java 提供了内置的观察者模式实现,可以通过 java.util.Observable 类和 java.util.Observer 接口来实现观察者模式。

import java.util.Observable;
import java.util.Observer;

public class ConcreteSubject extends Observable {
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        setChanged();
        notifyObservers();
    }
}

public class ConcreteObserver implements Observer {
    public void update(Observable o, Object arg) {
        int state = ((ConcreteSubject) o).getState();
        // 处理被观察者状态变化的逻辑
    }
}

在上述代码中,ConcreteSubject 类继承自 java.util.Observable 类,并使用 setChanged() 方法标记状态变化,然后调用 notifyObservers() 方法通知观察者。

ConcreteObserver 类实现了 java.util.Observer 接口,它的 update() 方法会在被观察者状态变化时被调用。

使用观察者模式

  💧以下是观察者模式的使用示例:

public class Client {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        ConcreteObserver observer1 = new ConcreteObserver(subject);
        ConcreteObserver observer2 = new ConcreteObserver(subject);
        
        subject.setState(1);
        // 输出:处理被观察者状态变化的逻辑
        // 输出:处理被观察者状态变化的逻辑
    }
}

在上述代码中,我们创建了一个具体的被观察者对象 ConcreteSubject 和两个具体的观察者对象 ConcreteObserver。通过将观察者注册到被观察者上,当被观察者状态发生变化时,观察者的 update() 方法会被调用。

总结

    观察者模式是一种有用的设计模式,它能够实现对象之间的一对多依赖关系,当一个对象的状态发生改变时,其所有依赖者都会得到通知并自动更新。通过观察者模式,我们可以实现松耦合的对象间通信,提高代码的灵活性和可维护性。


在这里插入图片描述


🐳结语

🐬初学一门技术时,总有些许的疑惑,别怕,它们是我们学习路上的点点繁星,帮助我们不断成长。

🐟积少成多,滴水成河。文章粗浅,希望对大家有帮助!

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

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

相关文章

uniapp 打包安卓apk (原生App)云打包

uniapp 打包安卓apk (原生App)云打包 hbuilder中操作 项目的一些配置appid DCloud appid 用途/作用/使用说明&#xff1a; https://ask.dcloud.net.cn/article/35907 右键我们项目目录-》发行-》原生APP-云打包 说明&#xff1a; 1. 打包安卓&#xff0c;只选择安卓打包项&…

基于pyqt和卷积网络CNN的中文汉字识别

直接上效果演示图&#xff1a; 通过点击按钮可以实现在画板上写汉字识别和加载图片识别两个功能。 视频演示和demo仓库地址在b站视频001期&#xff1a; 到此一游7758258的个人空间-到此一游7758258个人主页-哔哩哔哩视频 所有代码展示&#xff1a; 十分的简洁&#xff0c;主…

jni编程(windows+JDK11+clion)

JNI是Java Native Interface的缩写&#xff0c;通过使用 Java本地接口书写程序&#xff0c;可以确保代码在不同的平台上方便移植。 一、java代码 package org.example;public class Main {static {System.load("");}public static void main(String[] args) {Syste…

医学图像处理——读取和解读NII文件

一 预备知识 NII文件的存储格式网上有很多资料&#xff0c;在此只做一点简单的描述。nii是一种文件格式&#xff0c;它存储的是在空间中占有一定体积的小方块的物理位置和该位置对应的像素值。这个小方块我们也称之为体素(voxel)。存储的形式是一个三维数组(3D array)&#xf…

ESP32连接云服务器【WebSocket】

ESP32连接云服务器【ESP32宝塔面板】 文章目录 ESP32连接云服务器【ESP32宝塔面板】&#x1f468;‍&#x1f3eb;内容1&#xff1a;背景&#x1f468;‍⚖️内容2&#xff1a;服务器配置&#x1f468;‍&#x1f4bb;内容3&#xff1a;ESP32配置 &#x1f468;‍&#x1f3eb;…

k8s 就绪探针

【k8s 系列】k8s 学习二十&#xff0c;就绪探针 提起探针&#xff0c;不知兄dei 们是否有印象&#xff0c;之前我们分享过存活探针&#xff0c;分享存活探针是如何确保异常容器自动重启来保持应用程序的正常运行&#xff0c;感兴趣的可以查看文章 k8s 系列k8s 学习十七&#x…

windows下使用arp 协议

/ //自动扫描局域网存活主机 本程序是利用arp协议去获取局域网中的存活主机 arp协议概述 地址解析协议&#xff0c;即ARP&#xff08;Address Resolution Protocol&#xff09;&#xff0c;是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请…

音视频——码率、帧率越高越清晰?分辨率、像素、dpi的关系

一 前言 本期我介绍一下视频的一些基础概念&#xff0c;如帧率、码率、分辨率、像素、dpi、视频帧、I帧、P帧、gop等。我i初步学习音视频&#xff0c;给这些专业词汇进行扫盲 会解释多少码率是清晰的&#xff0c;是否帧率越高越流畅等问题。 这些概念是比较杂乱的&#xff0c…

CentOS 7镜像下载 以及 DVD ISO 和 Minimal ISO 等各版本的区别介绍

1.官网下载 官网下载地址&#xff1a;官网下载链接 点击进入下载页面&#xff0c;随便选择一个下载即可&#xff08;不推荐&#xff0c;推荐阿里云下载&#xff0c;见下文&#xff09; 阿里云下载站点&#xff08;速度非常快推荐&#xff09; 阿里云下载链接&#xff1a; http…

二叉树(上)——“数据结构与算法”

各位CSDN的uu们好呀&#xff0c;好久没有更新我的数据结构与算法专栏啦&#xff0c;今天&#xff0c;小雅兰继续来更新二叉树的内容&#xff0c;下面&#xff0c;让我们进入链式二叉树的世界吧&#xff01;&#xff01;&#xff01; 二叉树链式结构的实现 二叉树链式结构的实现…

MySQL进阶SQL语句(二)

MySQL进阶SQL语句&#xff08;二&#xff09; 一、MySQL进阶SQL语句1.1 连接查询1.2 CREATE VIEW视图&#xff0c;可以被当作是虚拟表或存储查询1.3 UNION 联集1.4 CASE1.5 空值(NULL) 和 无值() 的区别1.6 正则表达式 二、存储过程2.1 存储过程定义2.2 存储过程的优点2.3 存储…

【数据结构】栈和队列详解

⭐️ 往期相关文章 ✨链接1&#xff1a;数据结构和算法的概念以及时间复杂度空间复杂度详解 ✨链接2&#xff1a;【数据结构】手撕顺序表 ✨链接3&#xff1a;【数据结构】手撕单链表 ✨链接4&#xff1a;【数据结构】双向带头循环链表 ⭐️ 栈和队列 &#x1f320; 栈 栈是…

OpenCV对图片进行缩放处理

在下面的代码中,我会为你优化和解释这段程序: #include <opencv2/opencv.hpp>using namespace cv;int main() {// 读取源图片Mat srcImage = imread("../51_resize.jpg"

目标检测学习

目录 1、目标定位 2、特征点检测 3、目标检测 4、滑动窗口的卷积实现 5、Bounding Box 预测&#xff08;Bounding box predictions&#xff09; 6、交并化 7、非极大值抑制 8、Anchor Boxes 9、YOLO算法 1、目标定位 2、特征点检测 如何检测特征点&#xff08;以人的部…

HTML5新特性总结

新增语义化标签 新增了很多语义化标签&#xff0c;如header、footer、nav、article、section(页面中的某段文字&#xff0c;或文章中的某段文字)、aside、main 其中article标签里可以包含多个section&#xff1b; section强调的是分段或分块&#xff0c;若想将一块内容分成几…

【Vscode】解决 An SSH installation couldn‘t be found

【Vscode】解决 An SSH installation couldn‘t be found 背景描述&#xff1a;在vscode中使用ssh进行连接到时候&#xff0c;已经安装了ssh romote的plugin插件&#xff0c;但是在输入了ssh连接命令之后&#xff0c;仍然出现报错&#xff1a;an ssh installation could not be…

OpenCV 入门教程:中值滤波和双边滤波

OpenCV 入门教程&#xff1a;中值滤波和双边滤波 导语一、中值滤波二、双边滤波三、示例应用3.1 图像去噪3.2 图像平滑 总结 导语 在图像处理和计算机视觉领域&#xff0c;中值滤波和双边滤波是两种常见的滤波方法&#xff0c;用于平滑图像、去除噪声等。 OpenCV 提供了中值滤…

sap abap,forms,smartforms 导出pdf

4种方法&#xff1a; 1.安装pdf程序&#xff0c;Foxit Reader,先敲回车 自动带出&#xff0c;如下图&#xff1a; 直接打印就会弹出保存pdf文档路径&#xff0c;点保存。这种方式是最简单的&#xff0c;可 forms 和 smartforms 。 2. forms 和 smartforms 打印到spool 中&…

Maven工程开发中的继承与聚合

1. 聚合工程概念 设置一个空的maven工程&#xff0c;工程里面只有pom文件&#xff0c;另外将这个工程的打包方式设置为pom。 在聚合工程里面添加聚合工程里面管理的模块 2.聚合总结 3.继承 例如下面02工程继承上面的01工程&#xff0c;在02工程的pom文件中要配置要继承的父工…

保护你的JavaScript代码:深入了解JS混淆加密及其特点

当涉及到JavaScript代码的保护和隐藏时&#xff0c;混淆加密是一种常见的技术。它通过对代码进行转换和重组&#xff0c;使其难以理解和逆向工程。以下是JS混淆加密的几个特点以及它们各自的优缺点&#xff1a; 变量和函数名压缩&#xff1a; 特点&#xff1a;将代码中的变量和…