深入理解[观察者模式]原理与技术

2023-11-11

观察者模式(Observer Pattern)也叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式。这个模式的一个最重要的作用就是解耦。也就是将被观察者和观察者进行解耦,使得他们之间的依赖性更小,甚至做到毫无依赖。

观察者模式的定义:该模式定义了对象之间的一对多依赖关系,Subject 对象是一,Observer 对象是多。当 Subject 对象的状态发生改变时,所有依赖于该 Subject 对象的 Observer 对象都会得到通知,并且自动更新。

仔细分析定义,要精确理解观察者模式主要注意三点:

  1. 定义了对象间的一对多依赖关系。

  2. 当 Subject 对象的状态发生改变时,所有依赖于该 Subject 对象的 Observer 对象都会得到通知。

  3. Observer 对象得到通知后,会自动更新,而不是被动。

经过上面的分析,下面我用代码简单实现上述逻辑。

1.首先需要定义一个观察者对象,内部含有data数据(getter、setter、构造方法、toString)。

public class Observer {
    private String data;

    public Observer(String data) {
        this.data = data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Observer{" +
                "data='" + data + '\'' +
                '}';
    }
}

2.其次定义主题对象,主题对象内部提供观察者绑定(register)的接口,并且可以更新(update)所绑定的观察者对象。

public class Subject {
    private List<Observer> list = new ArrayList<>();

    public void register(Observer observer){
        list.add(observer);
    }

    public void update(){
        list.forEach(observer -> {
            observer.setData("new");
            System.out.println(observer.toString());
        });
    }

}

3.最后就是main方法。

    public static void main(String[] args) {
        Subject subject = new Subject();
        for (int i = 0; i < 3; i++) {
            Observer observer = new Observer("old");
            subject.register(observer);
            System.out.println(observer.toString());
        }
        System.out.println("update...");
        subject.update();
    }

控制台打印

Observer{data='old'}
Observer{data='old'}
Observer{data='old'}
update...
Observer{data='new'}
Observer{data='new'}
Observer{data='new'}

看到这里你也许会问:这就是观察者模式?这么简单?你莫不是在逗我?

是的,这就是观察者模式。我们从观察者模式的定义出发,抽取出关键的3点核心思想,对比代码和三点思想,是不是完美一致?百度一下"观察者模式",实现逻辑大都是复杂高深,其实就核心的思想来说,上面的示例足够了,其它扩展要以具体的业务需求来决定。比如:

  1. Subject 角色是应该定义成类?比如 内置的 java.util.Observable;还是应该定义成接口,以规避Java不支持多重继承的问题?

  2. 应该在什么时候订阅主题(或者说注册观察者)?是实例化观察者对象的同时?还是由客户自主决定?

  3. 是否应该实现取消订阅功能(或者说取消注册)?

  4. 主题对象通知观察者时,是否携带消息?换句话说,是“推”消息?还是“拉”消息?

  5. 是否支持多线程?

转载于:https://www.cnblogs.com/yueshutong/p/10918265.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解[观察者模式]原理与技术 的相关文章

随机推荐

  • SpringMVC中GET请求类型接收参数的两种方式

    1 PathVariable 方式接收URI参数 URI如 http localhost 8080 MyApp 123 Jack GetMapping user userId userName public String printMess
  • 将来时的表示

    一般将来时表示将来某一时刻的动作或状态 或将来某一段时间内经常发生的动作或状态 常常表示将来的时间状语连用 如 tomorrow 明天 next week 下周 in the future 将来 助动词will或shall 动词原形 表示将
  • 2021年总结

    一 目标回顾 一 工作 团队建设 学会管理团队 指引 领导团队前进 不太适合管理团队 技术 前端vue 熟悉 可以独立进行开发 并未达到 后端java熟悉springboot框架 可以独立进行开发项目 并且开发好一个项目 并达到 二 自我提
  • MYSQL设置密码时显示Failed! Error: SET PASSWORD has no significance for user ‘root‘@‘localhost‘ as the authe

    用这个命令进入mysql sudo mysql 在sql命令行输入以下命令回车 你就可以把密码改成mynewpassword ALTER USER root localhost IDENTIFIED WITH mysql native pa
  • 麒麟系统虚拟机安装教程

    作者 朱金灿 来源 clever101的专栏 为什么大多数人学不会人工智能编程 gt gt gt 1 首先得安装VM Ware软件 2 打开VM Ware 点击 文件 gt 新建虚拟机 3 进入新建虚拟机向导 点击下一步 如下图 4 安装来
  • elasticsearch-查询平分排序

    排序与相关性 默认情况下 返回的结果是按照 相关性 进行排序的 最相关的文档排在最前 在本章的后面部分 我们会解释 相关性 意味着什么以及它是如何计算的 不过让我们首先看看 sort 参数以及如何使用它 排序 为了按照相关性来排序 需要将相
  • idea生产junit类

    1 定义一个类 package com spring pro jdk8 construction test import lombok AllArgsConstructor import lombok Data import lombok
  • 本地运行hexo-theme-butterfly报错重定向次数过多

    本地运行hexo theme butterfly报错重定向次数过多 Github被墙了故选择使用Gitee 顺便搭建gitee page博客 使用了一个比较简约好看纯净的主题hexo theme butterfly 在这基础上进行配置 问题
  • 笔试,计算贡献值,2022-9-2

    计算时间区间的贡献值 若同一时间有多个应用程序 均分贡献值 每个vector表示一个应用的开始 结束时间段 一个应用可能有多个时间段 考虑 1 区间重叠 均分贡献值 2 浮点数计算 用整型处理单个时间会去掉小数 累计起来就错了 includ
  • 小样本中的自监督

    自监督脉络 SimCLR SimCLRV2 BYOL Moco SimSiam 一些典型操作 原图地址 When Does Self supervision Improve Few shot Learning 2019 ECCV 关键点 通
  • 计算机视觉(四):使用K-NN分类器对CIFAR-10进行分类

    1 引言 之前我们学习了KNN分类器的原理 现在让我们将KNN分类器应用在计算机视觉中 学习如何使用这个算法来进行图片分类 2 准备工作 创建项目结构如图所示 在datasets文件中下载数据集Cifar 10 k nearest neig
  • 基于Tensorflow搭建卷积神经网络CNN(花卉识别)保姆及级教程

    项目介绍 TensorFlow2 X 搭建卷积神经网络 CNN 实现人脸识别 可以识别自己的人脸哦 搭建的卷积神经网络是类似VGG的结构 卷积层与池化层反复堆叠 然后经过全连接层 最后用softmax映射为每个类别的概率 概率最大的即为识别
  • C#使用checked检查溢出

    在进行数值类型之间的强制转换时 可能会丢失信息 比如将 int 类型转换为 short 类型时 如果 int 类型会的值大于 short 类型所能存储的最大值 那么就会发生溢出 1 使用checked检查溢出 通常情况下 发生溢出时并不会自
  • this指向

    1 在全局环境中的this window 无论是否在严格模式下 在全局执行环境中 在任何函数体外部 this 都指向全局对象 use strict console log this window console log this windo
  • 联邦学习 深度学习对抗攻击

    联邦学习本身 联邦学习 实际上是一种加密的分布式机器学习技术 参与各方可以在不披露底层数据和底层数据的加密 混淆 形态的前提下共建模型 如果机构之间的数据无法互通 一家企业一家机构数据量有限 或者是少数巨头公司垄断大量数据 而小公司很难获得
  • 移动端Touch (触摸)事件

    一 常见的触摸事件 touchstart touchmove和touchend touchstart事件 当手指触摸屏幕时候触发 即使已经有一个手指放在屏幕上也会触发 touchmove事件 当手指在屏幕上滑动的时候连续地触发 在这个事件发
  • 怎么选择boost升压电路的电感?只要三个公式

    原文来自公众号 工程师看海 添加微信 chunhou0820 获取仿真文件 BOOST电源架构是一种非常经典的升压电源方案 它是利用开关管开通和关断的时间比率 维持稳定输出的一种开关电源 它以小型 轻量和高效率的特点被广泛应用在各行业电子设
  • 1-1、Qt基本概念以及界面绑定信号与槽的实例

    1 各种程序格式的选择方式 2 例子 新建mainwindow的项目 在ui拖动一个pushbuttton 点击界面下的信号与槽的部分 点击 然后选择发送者 信号 接收者 槽 一下为源码 sampl 1 pro Project create
  • yum提示 “Cannot retrieve metalink for repository: epel/x86_64” 的解决方法

    今天在centos7服务器上用yum的时候发现 yum命令不能用了 不管用yum什么命令都会出现如下提示 完整的错误提示如下 One of the configured repositories failed Unknown and yum
  • 深入理解[观察者模式]原理与技术

    观察者模式 Observer Pattern 也叫做发布 订阅 Publish Subscribe 模式 模型 视图 Model View 模式 这个模式的一个最重要的作用就是解耦 也就是将被观察者和观察者进行解耦 使得他们之间的依赖性更小