观察者模式——解决解耦的钥匙

● 观察者模式介绍

        观察者模式是一个使用频率非常高的模式,它最常用的地方是GUI系统、订阅——发布系统。因为这个模式的一个重要作用就是解耦,将被观察者和观察者解耦,使得它们之间依赖性更小,甚至做到毫无依赖。以CUI系统来说,应用的UI具有易变性,尤其是前期随着业务的改变或者产品的需要修改,应用界面也会经常性变化,但是业务逻辑基本变化不大,此时,GUI系统需要一套机制来应对这种情况,使得UI层与具体的业务逻辑解耦,观察者模式此时就派上用场了。

● 观察者模式的定义

        定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并被自动更新。

● 观察者模式的使用场景

        关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系;

        事件对接触发场景;

        跨系统的消息交换场景,如消息队列、事件总线的处理机制。

● 观察者模式的UML类图

        UML类图下图所示。

        

        角色介绍。

        Subject:抽象主题,也就是被观察者(Observable)的角色,抽象主题角色把所有观察者对象的引用在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。

        ConcreteSubject:具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发出通知,具体主题角色又叫做具体被观察者(Concrete Observable)角色。

        Observer:抽象观察者,该角色是观察者的抽象类,它定义了一个更新接口,使得在得到主题的更改通知时更新自己。

        ConcreteObserver:具体的观察者,该角色实现抽象观察者角色所定义的更新接口,以便在主题的状态发生变化时更新自身状态。

● 观察者模式的简单实现

        假设有一个开发技术前线网站,是一个聚合了关于Android、iOS新技术文章的开源库等内容的网站,在这里可以看到新技术、强大的开源库、新的信息,经常浏览这两网站不仅能够开阔眼界,也能让我们接触到前沿的科技信息。

        开发技术前线不仅是个内容发布页面,也支持用户邮箱订阅,每周发布周报后会将优质的内容推送给订阅用户,这种模式叫做发布——订阅模式,它的另一个名称是观察者模式。

        下面让我们来简单模拟一下开发技术前线的发布——订阅过程。

/**
 * 程序是观察者
 */
public class Coder implements Observer {
    public String name;

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

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Hi, " + name + ", DevTechFrontier更新新, 内容:" + arg);

    }

    @NonNull
    @Override
    public String toString() {
        return "码农:" + name;
    }
}
/**
 * DevTechFrontier 即开发技术前线,这个网站是被观察者角色,当它有更新时所有的观察者(这里是程序员)
 * 都接到相应的通知
 */
public class DevTechFrontier extends Observable {

    public void postNewPublication(String content) {
        //标识状态或者内容发生改变
        setChanged();
        //通知所有观察者
        notifyObservers(content);
    }
}
/**
 * 测试代码
 */
public class Test {
    public static void main(String[] args) {
        //被观察的角色
        DevTechFrontier devTechFrontier = new DevTechFrontier();
        Coder mrsimple = new Coder("mr.simple");
        Coder coder1 = new Coder("coder-1");
        Coder coder2 = new Coder("coder-2");
        Coder coder3 = new Coder("coder-3");

        //将观察者注册到可观察对象的观察者列表中
        devTechFrontier.addObserver(mrsimple);
        devTechFrontier.addObserver(coder1);
        devTechFrontier.addObserver(coder2);
        devTechFrontier.addObserver(coder3);

        //发布消息
        devTechFrontier.postNewPublication("新的一期开发技术前线周报发布啦!");
    }
}

        输出结果:

        可以看到所有订阅了开发技术前线的用户都收到了更新消息,一对多的订阅——发布系统就完成了。

        Oblerver和Observable是JDK中内置类型,可见观察者模式是非常重要的,这里Obsserver是抽象的观察者角色,Coder扮演的是具体观察者的角色:Observable对应的是抽象主题角色,DevTechFrontier则是具体的主题角色。Coder是具体的观察者,它们订阅了DevTechFrontier这个具体的可观察对象,当DevTechFrontier有更新时,会遍历所有观察者(这里是Coder),然后给这些观察者发布一个更新的消息,即调用Observer和Observable这些抽象类,因此,Coder和DevTechFrontier完全没有耦合,保证了订阅系统的灵活性、可扩展性。

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

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

相关文章

Linux安装配置awscli命令行接口工具及其从aws上传下载数据

官网技术文档有全面介绍:安装或更新 AWS CLI 的最新版本 - AWS Command Line Interface在系统上安装 AWS CLI。https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/getting-started-install.html#getting-started-install-instructionsawscli常用命令参考&…

uni-app学习笔记

目录 一、前期准备 1、项目认识 2、pages.json基本配置 3、创建页面 二、tabBar 1、获取图标 2、代码配置 三、基础认识 1、页面生命周期 2、App.vue应用生命周期 四、基础组件 1、scroll-view可滚动视图区域 2、提示框 3、swiper滑块视图容器 4、form表单组件 一…

番外---9.0 firewall 网络

### 网络配制方式: 00:依据图形界面形式配置(nmtui); 01:命令形式配置(nmcli); 02:使用系统菜单配置; 00:依据图形界面形式配置(nmtui&#xff0…

解决方案中word中分页符的使用

在投标方案中要善于使用“分页符”,尽可能少使用分节符号,没有分页符前,你每次修改你的标书或者文件,增加或者修改内容后。你的格式字段前后都是会发生变化,如何稳定的保证结构呢,那就是分页符的使用&#…

C语言映射表在串口数据解析中的应用

一、映射表在串口数据解析中的应用 1、数据结构 typedef struct {char CMD[CMDLen];unsigned char (*cmd_operate)(char *data); }Usart_Tab; 2、指令、函数映射表 static const Usart_Tab InstructionList[CMDMax] {{"PWON",PowOn},{"PWOFF",PowOff}…

antd的Table组件使用rowSelection属性实现多选时遇到的bug

前言 前端样式框架采用AntDesign时,经常会使用到Table组件,如果要有实现多选或选择的需求时往往就会用到rowSelection属性,效果如下 rowSelection属性属性值如下 问题 文档中并没有说明选择时以数据中的哪个属性为准,看官方案例…

docker 下安装mysql8.0

在docker中查询mysql镜像 PS C:\Users\admin> docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation……

答题测评考试小程序的效果如何

在线答题系统是一种在线练习、考试、测评的智能答题系统,适用于企业培训、测评考试、知识竞赛、模拟考试等场景,管理员可任意组题、随机出题,答题者成功提交后,系统自动判分。 多种题目类型,两种答题模式 练习模式&a…

Linux shell编程学习笔记20:case ... esac、continue 和break语句

一、case ... esac语句说明 在实际编程中,我们有时会请到多条件多分支选择的情况,用if…else语句来嵌套处理不烦琐,于是JavaScript等语言提供了多选择语句switch ... case。与此类似,Linux Shell脚本编程中提供了case...in...esa…

《人工智能算法图解》书籍推荐

书籍介绍 今天,人工智能在我们的生活中随处可见。它能推送我们喜欢的电视节目,帮助我们诊断疑难杂症,还能向我们推荐商品。因此,让我们掌握人工智能的核心算法,拥抱日新月异的智能世界吧。 与那些充斥着公式和术语的教…

麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包

原文链接:麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包 hello,大家好啊,今天给大家带来麒麟桌面操作系统软件仓库搭建的文章02-软件仓库添加新的软件包,本篇文章主要给大家介绍了如何在麒麟桌面操作系统2203-x86版本上&…

应用安全四十二:SSO安全

一、什么是SSO SSO是单点登录(Single Sign On)的缩写,是指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是比较流行的企业业务整合的解决方案之一。 身份验证过程依赖于双方之间的信任关…

【Git】git的下载安装与使用

目录 目录 一.下载安装 官方下载 淘宝镜像下载 安装 二.创建本地仓库 三.git的基本操作命令 git status git add . git commit -m " " 四.gitee(码云)的使用 配置ssh公钥 ​编辑 查看公钥 gitee创建仓库 将本地仓库的文件上传到远程仓库…

使用 ChatGPT 提升 LeetCode 刷题效率

文章目录 1 背景2 操作步骤 1 背景 在做 LeetCode 的 SQL 题库时, 想在本地调试, 需要在本地的数据库上创建表以及准备测试数据, 大家都是有经验的开发人员, 简单粗暴的办法就不讲了 可以借助 ChatGPT 的能力, 生产数据库的表以及测试数据的 sql, 提升刷题效率 2 操作步骤 将…

【计算机组成与设计】Chisel取指和指令译码设计

本次试验分为三个部分: 目录 设计译码电路 设计寄存器文件 实现一个32个字的指令存储器 设计译码电路 输入位32bit的一个机器字,按照课本MIPS 指令格式,完成add、sub、lw、sw指令译码,其他指令一律译码成nop指令。输入信号名…

【UE 材质】简单的闪闪发光材质

效果 节点 参考视频: https://www.bilibili.com/video/BV1uK411y737/?vd_source36a3e35639c44bb339f59760641390a8

【Liunx系统编程】命令模式3

目录 一,zip/unzip压缩指令 二,tar打包/压缩/解包指令 三,uname获取系统信息指令 四,Liunx下常用且重要的按键和关机指令 五,文件之间的互传 1,Windows与Linux之间的互传 2,Linux系统之间…

0xGame Web 2023

0xGame Web 2023 [Week 1] signin 这题直接看源码就行,easy [Week 1] baby_php OST /?aQNKCDZO&b240610708 HTTP/1.1 Host: 120.27.148.152:50014 Content-Length: 11 Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 Origin: htt…

K8s学习笔记——认识理解篇

1. K8s诞生背景 回顾应用的部署,经历了以下几个阶段: 传统部署:物理服务器上运行应用程序。虚拟机部署:物理服务器上安装虚拟机,在虚拟机上运行应用程序。容器部署:物理服务器上安装容器运行时&#xff0…

android studio 编译Telegram源码经验总结(2023-11-05)

前言 Telegram是一款强大的端到端加密IM,专注于安全性和速度,支持Android/IOS/Windows/macOS等平台,功能丰富,运行流畅,免费开源,代码具有学习和研究意义。 一、android telegram源码下载地址: …