3.7设计模式——Observer 观察者模式(行为型)

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并被自动更新。

结构

  • Subject(目标)知道它的观察者,可以有任意多个观察者观察同一个目标,提供注册和删除观察者对象的接口。
  • Observer(观察者)为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
  • ConcreteSubject(具体目标)将有关状态存入个ConcreteObserver对象;当它的状态发生改变时,向它的各个观察者发出通知。
  • ConcreteObserver(具体观察者)维护一个指向ConcreteSubject对象的引用;存储有关状态,这些状态应与目标的状态保持一致;实现Observer的更新接口,以使自身状态与目标的状态保持一致。

适用性

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两者封装在独立的对象中以使他们可以各自独立地改变和复用。
  • 当一个对象的改变需要同时改变其他对象,而不知道具体有多少个对象有待改变时。
  • 当一个对象必须通知其他对象,而它又不能假定其他对象时谁,既不希望这些对象时紧耦合的。

代码示例

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

// 观察者接口
interface Observer {
    void update();
}

// 目标类
class Subject {
    private List<Observer> 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();
        }
    }
}

// 具体目标类
class ConcreteSubject extends Subject {
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyObservers(); // 通知观察者状态改变
    }
}

// 具体观察者类
class ConcreteObserver implements Observer {
    private ConcreteSubject subject;

    public ConcreteObserver(ConcreteSubject subject) {
        this.subject = subject;
        this.subject.registerObserver(this); // 注册观察者
    }

    @Override
    public void update() {
        System.out.println("Observer updated, new state: " + subject.getState());
    }
}

// 测试
public class ObserverPatternExample {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        ConcreteObserver observer1 = new ConcreteObserver(subject);
        ConcreteObserver observer2 = new ConcreteObserver(subject);

        subject.setState(10);
        subject.setState(20);
    }
}
  • 在这个示例中,将创建一个名为Subject的目标类和一个名为Observer的观察者接口,然后实现具体目标类ConcreteSubject和具体观察者类ConcreteObserver。具体目标类将实现注册和删除观察者对象的接口,并在状态发生改变时通知观察者。具体观察者类将实现更新接口,以使自身状态与目标的状态保持一致。
  • ConcreteSubject维护了一个观察者列表,并在状态发生改变时通知观察者。具体观察者类ConcreteObserver实现了更新接口,并在状态发生改变时更新自身状态。在测试中,创建了一个具体目标对象和两个具体观察者对象,并通过改变具体目标的状态来观察具体观察者的更新。

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

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

相关文章

模块三:二分——153.寻找旋转排序数组中的最小值

文章目录 题目描述算法原理解法一&#xff1a;暴力查找解法二&#xff1a;二分查找疑问 代码实现解法一&#xff1a;暴力查找解法二&#xff1a;CJava 题目描述 题目链接&#xff1a;153.寻找旋转排序数组中的最小值 根据题目的要求时间复杂度为O(log N)可知需要使用二分查找…

电子负载仪的远端控制

前言 最近研究了电子负载仪的远端控制&#xff08;区别于前面板控制&#xff09;&#xff0c;主要是用于程序控制&#xff0c;避免繁琐复杂的人工控制&#xff0c;举了南京嘉拓和艾维泰科的例子。 有纰漏请指出&#xff0c;转载请说明。 学习交流请发邮件 1280253714qq.com …

基于JavaWEB的学生考勤管理系统(含论文)

本系统是用Java语言写的&#xff0c;基于JavaWEB的学生考勤管理系统 主要有三大模块&#xff0c;学生&#xff0c;教师和管理员模块&#xff0c;功能如下&#xff1a; 学生模块 教师模块&#xff1a; 管理员模块

深入了解Semaphore、CountDownLatch等实用工具的用法

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…

4月26(信息差)

&#x1f30d; 1170万台 华为跃升重回首位&#xff01;苹果跌至第五位 &#x1f384;工业软件大事件 —— OGG 1.0 发布&#xff0c;华为贡献全部源代码 ✨ 苹果发布 OpenELM&#xff1a;专为在设备端运行而设计的小型开源 AI 模型 1.FisheyeDetNet&#xff1a;首个基于鱼眼相…

LED驱动模块RSC6218A 5W-18W迷你高效驱动电源应用-REASUNOS(瑞森半导体)

一、LED驱动模块RSC6218A REASUNOS(瑞森半导体)通过持续投入研发&#xff0c;提升LLC应用技术&#xff0c;集成控制芯片与功率转换&#xff0c;成功推出新一代产品RSC6218A WSOP-16&#xff0c;延续瑞森LLC拓扑方案&#xff0c;时机趋势完全迎合我国双碳政策&#xff0c;电气特…

【Web】DASCTF X GFCTF 2024|四月开启第一局 题解(全)

目录 EasySignin cool_index SuiteCRM web1234 法一、条件竞争(没成功) 法二、session反序列化 EasySignin 先随便注册个账号登录&#xff0c;然后拿bp抓包改密码(username改成admin) 然后admin / 1234567登录 康好康的图片功能可以打SSRF&#xff0c;不能直接读本地文…

Docker网络模式与cgroup资源控制

前言 在 Docker 中&#xff0c;网络模式和 cgroup 资源控制作为关键功能&#xff0c;对于容器的性能优化和资源管理起着至关重要的作用。本文将介绍 Docker 的网络模式和cgroup资源控制&#xff0c;探讨不同网络模式的特点以及如何利用 cgroup 资源控制机制来有效管理容器的资…

不使用加减运算符实现整数加和减

文章目录 进位 进位 加粗 最近想出了不适用运算符实现加与减 首先按位与找出的是需不需要进位 按位与是两边同时为1,则为1,那么如果两边同时为1的话,是不是就该进位?所以我们用按位与来判断是否需要进位 然后再按位异或找出不同的位数 按位异或是两边不相等,也就是1 和 0的时…

SpringBoot源码阅读2-自动配置

SpringBoot源码阅读2-自动配置 在传统的Spring应用中&#xff0c;开发者需要手动配置一系列Web应用的核心组件&#xff0c;例如DispatcherServlet用于处理请求分发、ViewResolver用于视图解析、CharacterEncodingFilter用于字符编码过滤等。 然而在SpringBoot中只要引入了spr…

力扣HOT100 - 994. 腐烂的橘子

解题思路&#xff1a; 因为要记录轮数&#xff08;分钟数&#xff09;&#xff0c;所以不能一口气遍历到底&#xff0c;所以不能用深搜&#xff08;bfs&#xff09;&#xff0c;而要用广搜&#xff08;bfs&#xff0c;层序遍历&#xff09;。 先记录下新鲜橘子数&#xff0c;…

github+PicGo+obsidian来作为你的免费高效可靠图床吧

前提 一直以来 博客的图床问题都是个大问题 ,如何找到一个 可靠并且 方便的搭建方式 非常重要 今天介绍一种 githubpicGoobsidian的搭建方式 准备github库 生成个人github token 找到个人 设置 生成一个新token 或者已经有的直接用 新生成的token 需要记录下来 这可能是你最后…

在若依Ruoyi-Vue中集成mybatisplus实现mybatis增强

本文相关视频&#xff1a;https://www.bilibili.com/video/BV1Fi4y1q74p?p50&vd_source2894aa0e46c09ba98269f266128b6c6e 若依&#xff08;Ruoyi&#xff09;作为一款优秀的基于Spring Boot和Vue.js的企业级后台管理系统&#xff0c;其良好的架构设计和丰富的功能组件深…

13.JAVAEE之HTTP协议

HTTP 最新的版本应该是 HTTP/3.0 目前大规模使用的版本 HTTP/1.1 使用 HTTP 协议的场景 1.浏览器打开网站 (基本上) 2.手机 APP 访问对应的服务器 (大概率) 学习 HTTP 协议, 重点学习 HTTP 的报文格式 前面的 TCP/IP/UDP 和这些不同, HTTP 的报文格式,要分两个部分来看待.请求…

C# WinForm —— 10 单选按钮与复选框的介绍与使用

单选按钮 RadioButton 一组单选按钮中&#xff0c;只能选择一个&#xff0c;互相排斥 常用属性、事件&#xff1a; 属性用途(Name)单选按钮的ID&#xff0c;在代码里引用的时候会用到,一般以 rb开头Text单选按钮旁边显示的 文本信息Checked单选按钮的勾选状态Appearance控制单…

数据结构:最小生成树(Prim算法和Kruskal算法)、图的最短路径(Dijkstra算法和Bellman-Ford算法)

什么是最小生成树&#xff1f;Prim算法和Kruskal算法是如何找到最小生成树的&#xff1f; 最小生成树是指在一个连通图中&#xff0c;通过连接所有节点并使得总权重最小的子图。 Prim算法和Kruskal算法是两种常用的算法&#xff0c;用于寻找最小生成树。 Prim算法的步骤如下&…

通过 QEMU 试用 ESP32-C3 的安全功能

概述 ESP32-C3 系列芯片支持可信启动、flash 加密、安全存储等多种安全功能&#xff0c;还有专用外设来支持 HMAC 和数字签名等用例。这些功能所需的私钥和配置大多存储在 ESP32-C3 的 eFuse 存储器中。 启用安全功能时需要谨慎&#xff0c;因为使用到的 eFuse 存储器是一次…

实现SpringMVC底层机制(二)

文章目录 1. 动态获取spring配置文件1.修改SunWebApplicationContext.java2.修改SunDispatcherServlet.java 2.自定义Service注解1.需求分析2.编写Monster.java3.自定义Service注解4.编写Service接口MonsterService.java5.编写Service实现类MonsterServiceImpl.java6.修改SunWe…

数据结构系列-二叉树之前序遍历

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 这篇文章&#xff0c;我们主要的内容是对二叉树当中的前历的算法进行讲解&#xff0c;二叉树中的算法所要求实现的是 从根到左子树再到右子树的遍历顺序&#xff0c;可能这样不太…

C语言--基础面试真题

1、局部变量和静态变量的区别 普通局部变量和静态局部变量区别 存储位置&#xff1a; 普通局部变量存储在栈上 静态局部变量存储在静态存储区 生命周期&#xff1a; 当函数执行完毕时&#xff0c;普通局部变量会被销毁 静态局部变量的生命周期则是整个程序运行期间&#…
最新文章