【设计模式深度剖析】【7】【行为型】【观察者模式】

👈️上一篇:中介者模式

设计模式-专栏👈️

---

文章目录

  • 观察者模式
    • 英文原文
    • 直译
    • 如何理解?
  • 观察者模式的角色
    • 类图
    • 代码示例
  • 观察者模式的应用
    • 观察者模式的优点
    • 观察者模式的缺点
    • 观察者模式的使用场景

观察者模式

观察者模式Observer Pattern

观察者(Observer)也称发布-订阅(Publish-Subscribe),依赖(Dependents)。

观察者模式就像是一群订阅了报纸的读者,每当报纸有新版发布(状态更新),就会自动送到这些读者的手中,读者们可以根据自己的兴趣选择阅读哪些内容。这样,读者和报纸之间形成了一种灵活、低耦合的订阅-发布关系。

英文原文

The Observer Design Pattern is a behavioral design patternthat defines a one-to-many dependency between objects so that when one object (the subject) changes state, all its dependents (observers) are notified and updated automatically.

直译

观察者设计模式(Observer Design Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,以便当一个对象(主题)改变其状态时,其所有依赖者(观察者)都能得到通知并自动更新。

如何理解?

观察者模式就像是一群朋友在关注一个公告板。公告板是被观察者,而朋友们是观察者。当公告板上的内容发生变化(比如有新的活动通知)时,所有关注这个公告板的朋友们(观察者)都会收到通知,并根据通知的内容做出相应的反应(比如参加活动)。这样,即使公告板的内容经常变化,朋友们也不需要一直盯着它看,只要他们关注了公告板,就能在第一时间得到通知。这种模式不仅方便了朋友们获取信息,也减轻了公告板的负担。

观察者模式的角色

观察者模式通常包含以下几个角色:

  1. Subject(主题/被观察者):它知道有哪些观察者对其感兴趣,并提供了一个接口让观察者能注册自己、移除自己以及通知它们。
  2. Observer(观察者):为那些在主题状态改变时需要获得通知的对象定义一个更新接口。
  3. ConcreteSubject(具体主题):保存有关状态的信息,并提供一个接口供观察者查询状态、注册和移除自己。
  4. ConcreteObserver(具体观察者):实现观察者接口,以便在主题的状态发生改变时得到更新。

类图

在这里插入图片描述

代码示例

package com.polaris.designpattern.list3.behavioral.pattern07.observer.classicdemo;

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

interface Observer {
    void update(String message);
}


interface Subject {
    void registerObserver(Observer observer);

    void removeObserver(Observer observer);

    void notifyObservers(String message);
}

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

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

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

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

    // 这里可以添加其他方法来改变状态  
    public void setState(String state) {
        // 状态改变时,通知所有观察者  
        notifyObservers("Subject state has changed to: " + state);
    }
}

class ConcreteObserver implements Observer {
    private String name;

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

    @Override
    public void update(String message) {
        System.out.println(name + " has been notified: " + message);
    }
}


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

        System.out.println("registerObserver: Observer 1, Observer 2...");
        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        System.out.println("change subject state...");
        // 改变主题状态,这将触发所有注册的观察者的update方法  
        ((ConcreteSubject) subject).setState("New state");

        // 移除一个观察者
        System.out.println("remove observer1...");
        subject.removeObserver(observer1);

        System.out.println("change subject state...");
        // 再次改变主题状态,只会通知未移除的观察者  
        ((ConcreteSubject) subject).setState("Another new state");
    }
}

/* Output:
registerObserver: Observer 1, Observer 2...
change subject state...
Observer 1 has been notified: Subject state has changed to: New state
Observer 2 has been notified: Subject state has changed to: New state
remove observer1...
change subject state...
Observer 2 has been notified: Subject state has changed to: Another new state
*///~

上面示例当主题的状态改变时,所有注册的观察者都会收到通知并更新它们的状态。当某个观察者被移除后,它将不再收到通知。

观察者模式的应用

  1. 图形用户界面(GUI)开发:在GUI中,当用户与界面上的元素(如按钮、文本框)进行交互时,这些元素的状态可能会发生变化。观察者模式可以用于将这些状态变化通知给相应的观察者,触发相应的操作或更新界面。
  2. 消息通知系统:在聊天应用、社交媒体平台等需要实时消息传递的场景中,观察者模式可以实现消息的订阅与发布。当有新消息发布时,订阅该消息的观察者将收到通知并进行处理。
  3. 股票市场:股票交易所可以充当被观察者,而股票交易员可以充当观察者。当股票的价格、交易量等发生变化时,交易员将接收到通知并采取相应的行动。
  4. 日志记录系统:日志记录器可以充当被观察者,而观察者可以是日志分析器、报警系统等。当日志发生变化时,观察者将收到通知并执行相应的操作,如生成报告、发送警报等。

观察者模式的优点

  1. 解耦:观察者和被观察者是抽象耦合的,降低了它们之间的依赖关系,使得系统更加灵活和可扩展。
  2. 广播通信:支持一对多的依赖关系,简化了系统设计。
  3. 满足开闭原则:增加新的具体观察者或观察目标时,无需修改原有系统代码。

观察者模式的缺点

  1. 性能问题:如果一个被观察者对象有很多的直接和间接的观察者,将所有的观察者都通知到会花费很多时间,可能导致性能下降。
  2. 循环依赖问题:如果观察者和观察目标之间存在循环依赖,可能导致系统崩溃。
  3. 缺乏细节:观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

观察者模式的使用场景

  1. 当一个对象的改变需要同时改变其他对象时:可以使用观察者模式,将需要改变的对象作为观察者,将发生变化的对象作为被观察者。
  2. 当一个对象必须通知其他对象,但又不希望这些对象与它形成紧密耦合时:通过观察者模式,可以实现对象之间的松耦合关系。

---

👈️上一篇:中介者模式

设计模式-专栏👈️

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

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

相关文章

人工智能系统中毒是一个日益严重的威胁

咨询公司 Protiviti 最近与一家客户公司合作&#xff0c;该公司遭遇了一次不寻常的攻击&#xff1a;一名黑客试图操纵输入该公司人工智能系统的数据。 公司领导仍在调查此次攻击&#xff0c;公司怀疑黑客试图扭曲人工智能系统的输出。 此类攻击并非新鲜事&#xff0c;但在网络…

C语言详解(预编译)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

【code-server】Code-Server 安装部署

Code-Server 安装部署 1.环境准备 可以参考 https://coder.com/docs/code-server/install code-server的安装流程进行安装&#xff0c;主机环境是 Centos7 建议使用 docker 方式进行安装&#xff0c;可能会出现如下报错&#xff0c;需要升级 GNC 的版本&#xff0c;由于影响交…

RabbitMQ配置与交换机学习

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

《吸血鬼猎人D》观后感

前言 在B站无意中发现了一部动漫电影《吸血鬼猎人D》&#xff0c;看着封面还不错&#xff0c;就试着点开了视频&#xff0c;看了一会儿&#xff0c;发现画面很精美&#xff0c;人物造型高大威猛&#xff0c;肌肉线条清晰可见。如果我没记错的话&#xff0c;这种风格在日本动漫中…

C语言复习总结(含代码例程)

数据类型 基本类型&#xff1a;字符型、整型、浮点型、双精度浮点型 构造类型&#xff1a;数组、指针、结构体、共用体和枚举 字符型&#xff1a; 类型表示&#xff1a; (signed) char char -- 有符号 char 型 unsigned char -- 无符号 char 型 类型大小&#xff…

平衡树之B树

平衡树 ├── AVL 树 ├── 红黑树 ├── 2-3 树 ├── B 树 ├── Splay 树 └── Treap没研究明白&#xff0c;算啦。不写了

Opus从入门到精通(一)简介

Opus从入门到精通(一):简介 Opus是什么? Opus编解码器是专门设计用于互联网的交互式语音和音频传输。它是由IETF的编解码器工作组设计的&#xff0c;合并了Skype的SILK和Xiph. Org的CELT技术。 Opus编解码器的设计目的是处理广泛的交互式音频应用程序,包括IP语音,视频,游戏…

列出docker常用的命令

一、基础命令 docker run 创建并启动一个容器 docker ps 列出当前运行的容器 docker ps -a 列出所有容器&#xff0c;包括未运行的 docker stop 停止一个运行中的容器 docker start 启动一个已停止的容器 docker restart 重启容器 docker rm 删除一个或多个容器 docker pull 从…

揭秘Netflix背后的魔法:如何用三层架构打造个性化推荐帝国

推荐系统就像一家餐厅的菜单推荐 想象一下&#xff0c;你走进一家餐厅&#xff0c;面对琳琅满目的菜单&#xff0c;不知道点什么好。这时候&#xff0c;服务员给你推荐了几道菜&#xff0c;这些推荐是基于你以往的口味偏好和其他顾客的选择。Netflix的推荐系统也是类似的&…

浅谈golang字符编码

1、 Golang 字符编码 Golang 的代码是由 Unicode 字符组成的&#xff0c;并由 Unicode 编码规范中的 UTF-8 编码格式进行编码并存储。 Unicode 是编码字符集&#xff0c;囊括了当今世界使用的全部语言和符号的字符。有三种编码形式&#xff1a;UTF-8&#xff0c;UTF-16&#…

【PL理论】(21) 函数式语言:支持匿名函数 fun x → E | 设计递归函数 | 支持递归函数:let rec ...

&#x1f4ad; 写在前面&#xff1a;本章我们将讲解支持匿名函数&#xff0c;先回顾一下 F# 语言表示函数的方法&#xff0c;然后引出它。随后我们讲解一下如何设计递归函数&#xff0c;最后让我们的 F- 语言支持递归函数。 目录 0x00 回顾&#xff1a;F# 语言 0x01 支持匿名…

iOS--oc对象,类,和元类本质

iOS--oc对象&#xff0c;类&#xff0c;和元类本质 前言实例对象的具体结构自定义类对象的结构继承关系 类信息的存放对isa、superclass总结 前言 最近在学习runtime的过程中&#xff0c;发现其中消息发送-动态方法解析-消息转发中涉及到了大量的类与对象的底层知识&#xff0…

[NCTF 2018]flask真香

打开题目后没有提示框&#xff0c;尝试扫描后也没有什么结果&#xff0c;猜想是ssti。所以尝试寻找ssti的注入点并判断模版。 模版判断方式&#xff1a; 在url地址中输入{7*7} 后发现不能识别执行。 尝试{{7*7}} ,执行成功&#xff0c;继续往下走注入{{7*7}}&#xff0c;如果执…

ubuntu certbot 生成https ssl证书

一、安装certbot应用 sudo apt update sudo apt install certbot python3-certbot-nginx二、生成证书 # 泛域名&#xff1a; certbot certonly -d *.你的主域名 --manual --preferred-challenges dns# 主域名&#xff1a; certbot certonly -d 你的主/子域名 --manual --pref…

java实战——图书管理项目

文章目录 项目所需要的技术栈项目演示项目准备工作环境准备数据库数据准备 前后端交互分析&#xff08;前端代码我们使用现成&#xff09;图书列表界面的创建查看前端发送的请求根据前端接收的返回值来编写model层根据请求编写controller层根据controller编写Service根据Servic…

代码随想录算法训练营第五十七 | 739. 每日温度、 496.下一个更大元素 I、503.下一个更大元素II

## 739. 每日温度 这里是引用 https://programmercarl.com/0739.%E6%AF%8F%E6%97%A5%E6%B8%A9%E5%BA%A6.html 第一次接触单调栈&#xff0c;看完视频讲解之后思路很清晰&#xff0c;对单调栈能够解决的问题类型有大致了解 class Solution { public:vector<int> dailyTemp…

SARscape5.6.2干涉叠加处理效率提升

SARscape5.6.2于2022年5月正式发布&#xff0c;包含若干更新和优化。干涉叠加处理模块在处理速度方面持续提升&#xff0c;表现在&#xff1a;PS干涉工作流处理、第一次反演和第二次反演优化&#xff0c;速度提升&#xff1b;SBAS处理干涉图生成和干涉图优化速度提升&#xff0…

C# WPF入门学习主线篇(二十)—— 资源和样式

C# WPF入门学习主线篇&#xff08;二十&#xff09;—— 资源和样式 欢迎来到C# WPF入门学习系列的第二十篇。在前面的章节中&#xff0c;我们探讨了布局管理及各种控件的使用。本篇博客将重点介绍WPF中的资源&#xff08;Resource&#xff09;和样式&#xff08;Style&#xf…

vue3+vite+ts 使用webrtc-streamer播放海康rtsp监控视频

了解webrtc-streamer webrtc-streamer 是一个使用简单机制通过 WebRTC 流式传输视频捕获设备和 RTSP 源的项目&#xff0c;它内置了一个小型的 HTTP server 来对 WebRTC需要的相关接口提供支持。相对于ffmpegflv.js的方案&#xff0c;延迟降低到了0.4秒左右&#xff0c;画面的…