二十三种设计模式全面解析-当你的对象需要知道其他对象的状态变化时,观察者模式是你的救星!

news2024/12/22 9:45:25

在软件设计的世界中,有一种设计模式以其简洁而强大的特性闪耀着光芒,它就是——观察者模式(Observer Pattern)。这个模式它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,为我们创造了一种优雅的编程体验。本文将带你深入探讨,观察者模式的神秘面纱,揭示其强大之处,让你在面对复杂系统时能游刃有余。


1、什么是观察者模式

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象发生变化时,它会通知所有的观察者对象,使它们能够自动更新自己。在观察者模式中,主题对象和观察者对象之间是松耦合的,它们之间并不直接依赖,而是通过抽象的接口或抽象类进行交互。


2、适用场景

观察者模式适用于以下场景:

  • 当一个对象的改变需要同时改变其他对象的时候。
  • 当一个对象需要将自己的改变通知其他对象,而又不希望知道具体有多少个对象需要通知时。
  • 当一个对象需要通知其他对象,但是又希望这些对象是动态的,即不需要在编译时就确定下来。

例如,一个新闻发布机构可以作为主题对象,而订阅该机构新闻的用户可以作为观察者对象。当新闻发布机构发布新闻时,所有订阅该机构新闻的用户都会收到通知。


3、技术要点

观察者模式包含以下几个核心角色:

  • 主题(Subject):维护一组观察者对象,提供注册和删除观察者对象的方法,并通知观察者对象状态变化。
  • 观察者(Observer):定义了一个更新接口,用于在主题状态变化时接收通知。
  • 具体主题(Concrete Subject):继承或实现主题接口,实现注册、删除和通知观察者对象的方法。
  • 具体观察者(Concrete Observer):继承或实现观察者接口,实现更新接口,以便在主题状态变化时更新自己的状态。

4、观察者模式案例

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

interface Observer {
    public void update(String message);
}

interface Subject {
    public void attach(Observer observer);
    public void detach(Observer observer);
    public void notifyObservers();
}

class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<Observer>();
    private String message;

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

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

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

    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }
}

class ConcreteObserver implements Observer {
    private String name;

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

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

public class ObserverPatternDemo {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

        ConcreteObserver observer1 = new ConcreteObserver("Observer 1");
        ConcreteObserver observer2 = new ConcreteObserver("Observer 2");
        ConcreteObserver observer3 = new ConcreteObserver("Observer 3");

        subject.attach(observer1);
        subject.attach(observer2);

        subject.setMessage("Hello World!");

        subject.detach(observer2);
        subject.attach(observer3);

        subject.setMessage("Goodbye World!");
    }
}

在这里插入图片描述


在上面的代码中,我们定义了一个 Subject 接口和一个 Observer 接口。

Subject 接口定义了注册、删除和通知观察者的方法,而 Observer 接口定义了更新方法。


然后我们定义了一个具体的主题类 ConcreteSubject,它维护了一个观察者列表,并实现了 Subject 接口中的方法。

我们还定义了一个具体的观察者类 ConcreteObserver,它实现了 Observer 接口中的更新方法。在 ObserverPatternDemo 类中,我们创建了一个具体的主题对象 subject 和三个具体的观察者对象 observer1observer2observer3


我们首先将 observer1observer2 注册到 subject 中,然后改变 subject 的状态,这会导致 observer1observer2 的更新方法被调用。

接着我们将 observer2subject 中删除,并将 observer3 注册到 subject 中,然后再次改变 subject 的状态,这会导致 observer1observer3 的更新方法被调用。


这个案例代码展示了如何使用观察者模式来实现对象之间的松耦合,并且可以在运行时动态地选择不同的观察者,而不需要修改客户端代码。


总结:

观察者模式是一种非常有用的设计模式,它可以帮助我们实现对象之间的松耦合,让多个对象能够同时监听某一个主题对象。


然而,设计模式世界中还有许多其他精彩的故事等待我们探索。在下一篇博文中,我们将深入研究另一个引人入胜的设计模式,为你带来更多惊喜。敬请期待!


好了,今天的分享到此结束。如果觉得我的博文帮到了您,您的点赞和关注是对我最大的支持。如遇到什么问题,可评论区留言。


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高斯积分-Gaussian Quadrature

https://mathworld.wolfram.com/GaussianQuadrature.html

pyinstaller 打包pyqt6等ui文件为exe可执行程序的方法

刚开始使用auto-py-to-exe打包pyqt6的程序&#xff0c;折腾好半天都会出错&#xff0c;关键打包出来的exe单文件有快100兆了&#xff0c;真大啊&#xff01; auto-py-to-exe有图形界面&#xff0c;看起来比较直观。 还有中文语言&#xff0c;对使用者比较友善&#xff0c;可以…

大数据研发工程师课前环境搭建

大数据研发工程师课前环境搭建 第一章 VMware Workstation 安装 在Windows的合适的目录来进行安装&#xff0c;如下图 1.1 双击打开 1.2 下一步&#xff0c;接受协议 1.3 选择安装位置 1.4 用户体验设置 1.5 快捷方式 已经准备好安装&#xff0c;点击安装 1.6 安装中 1.7 安装…

linux基本指令总结--文件和目录

前言&#xff1a; 想要学好Linux操作系统&#xff0c;理解并熟悉一些基本的指令是必要的&#xff0c;下面我将整理出关于文件和目录操作的一些基本指令和用法&#xff0c;我的linux环境部署在服务器端&#xff0c;使用xshell软件进行远程操作。 本章指令整合&#xff1a; ls查…

【技术追踪】SAM(Segment Anything Model)代码解析与结构绘制之Mask Decoder

论文&#xff1a;Segment Anything   代码&#xff1a;https://github.com/facebookresearch/segment-anything 系列篇&#xff1a;   &#xff08;1&#xff09;【技术追踪】SAM&#xff08;Segment Anything Model&#xff09;代码解析与结构绘制之Image Encoder   &am…

如何在el-tree懒加载并且包含下级的情况下进行数据回显-01

在项目中做需求&#xff0c;遇到一个比较棘手的问题&#xff0c;el-tree懒加载在包含下级的时候&#xff0c;需要做回显&#xff0c;将选中的数据再次勾选上&#xff0c;在处理这个需求的时候有两点是比较困难的&#xff1a; el-tree是懒加载的&#xff0c;包含下级需要一层一…

DPDK初始化

rte_eal_init │ ├──rte_cpu_is_supported&#xff1a;检查cpu是否支持 │ ├──rte_atomic32_test_and_set&#xff1a;操作静态局部变量run_once确保函数只执行一次 │ ├──pthread_self() 获取主线程的线程ID,只是用于打印 │ ├──eal_reset_internal_config&#x…

Python 利用PIL由多张图片合成gif动画

Python 由多张图片合成gif动画 案例 import os figure_save_path "file_fig_test" import warnings warnings.filterwarnings("error") import numpy as np np.random.seed(0) import matplotlib.pyplot as plt from PIL import Image import timenum 1…

​软考-高级-系统架构设计师教程(清华第2版)【第16章 嵌入式系统架构设计理论与实践(P555~613)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第16章 嵌入式系统架构设计理论与实践&#xff08;P555~613&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

将ArduinoIDE库文件移动到其他磁盘的方法

本文主要介绍更改软件包位置Arduino IDE &#xff08;含2.0以上版本&#xff09;的方法。 Arduino IDE 默认将软件包安装到 C 盘&#xff0c;如果你使用的开发板较多&#xff0c;产生的库文件很大&#xff0c;会导致 C 盘可用空间不足&#xff0c;博主只用了ESP开发板&#xf…

GCD:异步同步?串行并发?一文轻松拿捏!

GCD 文章目录 GCD进程线程进程与线程的关系进程与线程的区别 任务&#xff08;执行的代码&#xff09;队列线程与队列的关系 队列任务**同步执行任务&#xff08;sync&#xff09;**辅助方法**异步执行任务&#xff08;async)**总结栅栏任务迭代任务 队列详细属性QoSAttributes…

CF1899 G. Unusual Entertainment [二维数点/二维偏序]

传送门:CF [前题提要]:没什么好说的,区域赛爆炸之后发愤加训思维题.秒了div3 A~F的脑筋急转弯,然后被G卡了,树剖dfs序的想法已经想到了,题目也已经化简为两个线段是否存在一个合法位置了.但是MD不会二维数点,用一个树剖扫描线搞来搞去最后还是Tle.果然如下图所说:科技还是十分…

掌握未来技术趋势,Python编程引领人工智能时代

掌握未来技术趋势&#xff0c;Python编程引领人工智能时代 摘要&#xff1a;Python作为一种高级编程语言&#xff0c;在人工智能领域中扮演着越来越重要的角色。本文将通过介绍Python编程的特点、应用场景及发展前景&#xff0c;展望Python未来的发展趋势&#xff0c;并结合代…

搭建mysql主从错误集合

1 mysqld --verbose --help --log-bin-index/tmp/tmp.Frnt2oibYI mysqld: Cant read dir of /etc/mysql/conf.d/ my.cnf是在/etc/mysql/conf.d/文件夹下&#xff0c;所以挂载的时候不要写/etc/mysql 2 COLLATION utf8_unicode_ci is not valid for CHARACTER SET latin1 配…

Windows10下Maven3.9.5安装教程

文章目录 1.下载maven2.安装3.配置系统变量3.1.新建系统变量 MAVEN_HOME3.2.编辑系统变量Path 4.CMD命令测试是否安装成功5.配置maven本地仓库6.配置国内镜像仓库 1.下载maven 官网 https://maven.apache.org/download.cgi 点击下载。 2.安装 解压到指定目录 D:\installSoft…

springcloudalibaba-3

一、Nacos Config入门 1. 搭建nacos环境【使用现有的nacos环境即可】 使用之前的即可 2. 在微服务中引入nacos的依赖 <!-- nacos配置依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-…

​软考-高级-系统架构设计师教程(清华第2版)【第18章 安全架构设计理论与实践(P648~690)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第18章 安全架构设计理论与实践&#xff08;P648~690&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

【算法每日一练]-图论(保姆级教程 篇5(LCA,最短路,分层图)) #LCA #最短路计数 #社交网络 #飞行路线 # 第二短路

今天讲最短路统计和分层图 目录 题目&#xff1a;LCA 思路&#xff1a; 题目&#xff1a;最短路计数 思路&#xff1a; 题目&#xff1a;社交网络 思路&#xff1a; 题目&#xff1a;飞行路线 思路&#xff1a; 题目&#xff1a;第二短路 思路&#xff1a; 题目&a…

轻量服务器和云服务器的区别,轻量应用服务器和云服务器区别对比

在云计算时代&#xff0c;服务器作为互联网应用的基础设施&#xff0c;扮演着重要的角色。对于个人用户、个人开发者、学生用户和个人站长来说&#xff0c;选择一款适合自己的服务器是一个关键的决策。本文将介绍轻量服务器和标准云服务器的优点和应用场景&#xff0c;帮助读者…

深入理解ResNet网络:实现与应用

Resnet 在深度学习领域&#xff0c;卷积神经网络&#xff08;CNN&#xff09;是一种非常重要的模型&#xff0c;它在图像识别、目标检测等领域取得了显著的成果。然而&#xff0c;随着网络层数的增加&#xff0c;梯度消失和梯度爆炸问题变得越来越严重&#xff0c;导致训练深层…