观察者模式(推模型+拉模型)

2023-11-03

观察者模式(Observer Pattern):当一个对象被修改时,会自动通知它的依赖对象

 

现在我们是新闻社,要向所有新闻订阅者推送新闻。那么该如何实现呢?

经过思考我们不难发现一家新闻社一般对应的是多个新闻订阅者。

那么我们先从新闻社开始入手,想一想新闻社要具备哪些基本功能呢?

1.新闻,2.有哪些订阅者,3.添加订阅者,4.取消订阅者,5推送新闻。

//新闻社
public class Newspaper {
	
	private String news;//新闻
	
	public List<Subscriber> subscribers = new ArrayList<>();//存储所有订阅者
	
	public void addSubscriber(Subscriber subscriber){//添加订阅者
		subscribers.add(subscriber);
	}
	
	public void removeSubscriber(Subscriber subscriber){//删除订阅者
		subscribers.remove(subscriber);
	}
	
	public void sendNews(){//给所有订阅者发送新闻,此处可以改进,后面讲到
		for (Subscriber subscriber : subscribers) {
			subscriber.receiveNews(news);
		}
	}

	public String getNews() {
		return news;
	}

	public void setNews(String news) {
		this.news = news;
	}
	
}

新闻社已经规划好,现在考虑订阅者,订阅者是多个,那么我们先定义一套订阅者的标准(接口),并考虑订阅者需要做的事:

1.接收新闻

//订阅者
public interface Subscriber {
	void receiveNews(String news);//接收新闻
}

标准写好了,现在有两个客户联系上我们,要成为我们的订阅者:

//订阅者One
public class SubscriberOne implements Subscriber{

	@Override
	public void receiveNews(String news) {
		System.out.println("订阅者One,接收到新闻:"+news);	
	}

}

//订阅者Two
public class SubscriberTwo implements Subscriber{

	@Override
	public void receiveNews(String news) {
		System.out.println("订阅者Two,接收到新闻:"+news);	
	}

}

规划了新闻社,与订阅者签了合同,现在来实际操作一下:

	public static void main(String[] args) {
		//建立真正的新闻社
		Newspaper newspaper = new Newspaper();
		//将订阅者One加入
		newspaper.addSubscriber(new SubscriberOne());
		//将订阅者Two加入
		newspaper.addSubscriber(new SubscriberTwo());
		//设置新闻
		newspaper.setNews("70周年");
		//发送新闻
		newspaper.sendNews();
	}

观察者模式(推模型),运行结果:

订阅者One,接收到新闻:70周年
订阅者Two,接收到新闻:70周年

不难发现,这个设置新闻和发送新闻,其实可以整合一下,第一种直接发送新闻内容就行,第二种设置新闻时,自动推送给所有订阅者,但是都还属于推模型,先来实现第一种,改造新闻社:

//新闻社
public class Newspaper {

	public List<Subscriber> subscribers = new ArrayList<>();//存储所有订阅者
	
	public void addSubscriber(Subscriber subscriber){//添加订阅者
		subscribers.add(subscriber);
	}
	
	public void removeSubscriber(Subscriber subscriber){//删除订阅者
		subscribers.remove(subscriber);
	}
	
	public void sendNews(String news){//直接给所有订阅者发送新闻★★★
		for (Subscriber subscriber : subscribers) {
			subscriber.receiveNews(news);
		}
	}
	
}

重新运行下:

	public static void main(String[] args) {
		//建立真正的新闻社
		Newspaper2 newspaper = new Newspaper2();
		//将订阅者One加入
		newspaper.addSubscriber(new SubscriberOne());
		//将订阅者Two加入
		newspaper.addSubscriber(new SubscriberTwo());
		//直接发送新闻
		newspaper.sendNews("70周年");
	}

结果一致:

订阅者One,接收到新闻:70周年
订阅者Two,接收到新闻:70周年

现在来实现第二种,改造新闻社:

//新闻社
public class Newspaper{
	
	private String news;//新闻
	
	public List<Subscriber> subscribers = new ArrayList<>();//存储所有订阅者
	
	public void addSubscriber(Subscriber subscriber){//添加订阅者
		subscribers.add(subscriber);
	}
	
	public void removeSubscriber(Subscriber subscriber){//删除订阅者
		subscribers.remove(subscriber);
	}
	
	public void sendNews(){//给所有订阅者发送新闻
		for (Subscriber subscriber : subscribers) {
			subscriber.receiveNews(news);
		}
	}

	public String getNews() {
		return news;
	}

	public void setNews(String news) {
		this.news = news;
		sendNews();//在设置新闻时,自动推送给所有订阅者★★★
	}
	
}

重新运行一下:

	public static void main(String[] args) {
		//建立真正的新闻社
		Newspaper3 newspaper = new Newspaper3();
		//将订阅者One加入
		newspaper.addSubscriber(new SubscriberOne());
		//将订阅者Two加入
		newspaper.addSubscriber(new SubscriberTwo());
		//设置新闻,并自动推送
		newspaper.setNews("70周年");
	}

运行结果一致:

订阅者One,接收到新闻:70周年
订阅者Two,接收到新闻:70周年

以上是推模型的实现方法,那什么是拉模型呢?先看这两个地方:

新闻社推送的都是新闻,并且订阅者订阅的是新闻的内容。我们是否可以不推新闻,而是把新闻社提供给订阅者,需要时订阅者自己去获取新闻呢?下面重新改造一下:

//新闻社
public class Newspaper {
	
	private String news;//新闻
	
	public List<Subscriber> subscribers = new ArrayList<>();//存储所有订阅者
	
	public void addSubscriber(Subscriber subscriber){//添加订阅者
		subscribers.add(subscriber);
	}
	
	public void removeSubscriber(Subscriber subscriber){//删除订阅者
		subscribers.remove(subscriber);
	}
	
	public void sendNewspaper(){//提供的不再是新闻,而是新闻社★★★
		for (Subscriber subscriber : subscribers) {
			subscriber.receiveNewspaper(this);//将自己提供给订阅者
		}
	}

	public String getNews() {
		return news;
	}

	public void setNews(String news) {
		this.news = news;
		sendNewspaper();//设置新闻时,将新闻社提供给订阅者★★★
	}
}


//订阅者定义
public interface Subscriber {
	void receiveNewspaper(Newspaper newspaper);//接收新闻社★★★
}
//订阅者One
public class SubscriberOne implements Subscriber{

	@Override
	public void receiveNewspaper(Newspaper newspaper) {
		String news = newspaper.getNews();//订阅者One自行从新闻社获取新闻★★★
		System.out.println("订阅者One,接收到新闻:"+news);	
	}

}
//订阅者Two
public class SubscriberTwo implements Subscriber{

	@Override
	public void receiveNewspaper(Newspaper newspaper) {
		String news = newspaper.getNews();//订阅者Two自行从新闻社获取新闻★★★
		System.out.println("订阅者Two,接收到新闻:"+news);	
	}

}

拉模型已经写好,现在运行一下:

	public static void main(String[] args) {
		//建立真正的新闻社
		Newspaper newspaper = new Newspaper();
		//将订阅者One加入
		newspaper.addSubscriber(new SubscriberOne());
		//将订阅者Two加入
		newspaper.addSubscriber(new SubscriberTwo());
		//设置新闻
		newspaper.setNews("70周年");
	}

运行结果

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

观察者模式(推模型+拉模型) 的相关文章

  • 设计模式--观察者模式

    观察者模式 属于行为型模式基本原理 当一个对象被修改时 会自动通知它的依赖对象 主要流程 1 创建一个对象 存储它的所有依赖对象 2 在对象被修改的时候 通知所有依赖的对象 3 创建依赖对象 有统一的刷新方法 注意 避免循环依赖 inclu
  • JavaScript设计模式(四)——策略模式、代理模式、观察者模式

    个人简介 个人主页 前端杂货铺 学习方向 主攻前端方向 正逐渐往全干发展 个人状态 研发工程师 现效力于中国工业软件事业 人生格言 积跬步至千里 积小流成江海 推荐学习 前端面试宝典 Vue2 Vue3 Vue2 3项目实战 Node js
  • Head First Design Mode(12)-状态模式

    该系列文章系个人读书笔记及总结性内容 任何组织和个人不得转载进行商业活动 状态模式 状态模式和策略模式是 双胞胎 在出生时才分开 策略模式是围绕可以互换的算法来创建成功业务的 状态模式则是通过改变对象内部的状态来帮助对象控制自己的行为 状态
  • 1.单例模式之饿汉式

    单例模式总结 特点 构造方法私有 提供一个全局访问点 实现方式 有很多 分四篇分别总结1 饿汉式 2 懒汉式 3 注册式 4 ThreadLocal 优点 内存中只有一个实例 减少内存开销 避免对资源多重占用 设置全局访问点 严格控制访问
  • Java 动态代理和静态代理 详解(结合代码实列)

    文章目录 Java 动态代理和静态代理的区别 下面是一个结合代码示例 运行上述代码 输出如下 总结 Java 动态代理和静态代理的区别 动态代理和静态代理是两种不同的代理模式 它们在代理对象的创建和使用方式上有所不同 静态代理 静态代理是在
  • 3.观察者模式C++用法示例

    观察者模式 一 观察者模式 1 作用 2 适用场景 3 实现要素 二 C 程序示例 一 观察者模式 观察者模式 Observer Pattern 是一种行为型设计模式 它定义了一种一对多的依赖关系 让多个观察者对象同时监听一个主题对象 当主
  • 我去公司面试,人事经理面试没有过,我却把责任链模式学会了

    设计模式在开发当中是运用特别多的 设计模式就是参照我们日常生活特性 抽象出特性 从而某种实现达到具体要求 当然这当中一定是灵活转变 责任链正式拉开序幕 我去某某互联网公司去面试 好的方向的流程大致应该是 你上招聘软件投递简历 简历筛选通过
  • 设计模式之Adapter模式

    今天这篇文章 我们来讲将设计模式中的 Adapter模式 中文就是 适配器模式 先说说一个生活中适配器模式的案例 有助于理解 现在有一个100伏特的交流电源 我现在想给笔记本充电 但是笔记本只能用12伏特的直流电 那我们是不是不能用这个电源
  • Java之美[从菜鸟到高手演变]之设计模式四

    在阅读过程中有任何问题 请及时联系 egg 邮箱 xtfggef gmail com 微博 http weibo com xtfggef 转载请说明出处 http blog csdn net zhangerqing 其实每个设计模式都是很重
  • Java设计模式-迪米特法则

    迪米特法则 Low Of Demeter 定义 一个对象应该对其他对象保持最少的了解 问题由来 类与类之间的关系越密切 耦合度越大 当一个类发生改变时 对另一个类的影响也越大 解决方案 尽量降低类与类之间的耦合 自从我们接触编程开始 就知道
  • Gof23设计模式之命令模式

    1 概述 将一个请求封装为一个对象 使发出请求的责任和执行请求的责任分割开 这样两者之间通过命令对象进行沟通 这样方便将命令对象进行存储 传递 调用 增加与管理 2 结构 命令模式包含以下主要角色 抽象命令类 Command 角色 定义命令
  • 细说设计模式七大原则(6):开闭原则

    2 8 1 基本介绍 英文名 Open Closed Principle OCP 定义 一个软件实体如类 模块和函数应该对扩展开放 对修改关闭 开闭原则是编程中最基础 最重要的设计原则 一个软件实体如类 模块和函数应该对扩展开放 对提供方
  • C++ 大话设计之《观察者模式》(优缺点,设计原理,常用场景)

    观察者模式是一种行为型模式 优点 松散耦合 观察者模式提供了一种松散耦合的设计 使得当一个对象的状态发生变化时 它不需要知道其他对象是如何使用这些信息的 这使得系统更容易扩展和维护 动态关联 观察者模式允许在运行时动态地添加或删除观察者 而
  • 观察者模式 & 发布-订阅模式(设计模式与开发实践 P8)

    文章目录 观察者模式 运用 实现 观察者模式 定义 他用来定义对象之间一种一对多的依赖关系 当一个对象状态发生改变时 所有依赖他的对象都会得到通知 运用 如果我们使用过 DOM 上的事件函数 那就接触过观察者模式 document body
  • [大话设计模式C++版] 第14章 老板回来,我不知道 —— 观察者模式

    源码可以在这里找到 大话设计模式C 版 双向耦合的代码 Secretary h 秘书类 include
  • Java设计模式(25):责任链模式(职责链模式)

    25 责任链模式 25 1 问题引入 采购需求 采购员需要采购一批教学器材 对器材采购金额有分级审批权限 如果金额小于等于3000元 由教学主任审批 0 lt x lt 3000 如果金额小于等于10000元 由院长审批 3000 lt x
  • 【JAVA设计模式】之桥接模式(BridgePattern)

    桥接模式的作用是将两样东西连接起来 比如桥梁把河的两岸连接起来 桥接模式把 类的功能层次结构 和 类的实现层次结构 连接起来 类的层次结构 类的功能层次 父类通过定义抽象方法来定义接口API 类的实现层次 子类通过实现具体方法来实现接口AP
  • 观察者模式和发布订阅模式

    观察者模式与发布订阅模式的区别 1 观察者模式中只有观察者和被观察者 发布订阅模式中有发布者 订阅者 调度中心 2 观察者模式是被观察者发生变化时自己通知观察者 发布订阅模式是通过调度中心来进行分布订阅操作 vue2中响应式数据就是由Obj
  • 【githubshare】无需编写一行代码,即可自动为静态数据集生成只读 API,快速完成静态数据的加载调用

    推荐 GitHub 上一款开源的开发者工具 ROAPI 无需编写一行代码 即可自动为静态数据集生成只读 API 快速完成静态数据的加载调用 GitHub github com roapi roapi 静态数据集所支持的格式 包括 CSV J
  • Java监听器与观察者模式

    Java监听器与观察者模式 Java中的监听器 Listener 和观察者模式 Observer Pattern 都是用于处理对象间的事件通知和响应的设计模式 它们的目的是在对象之间建立一种松散的耦合 使得一个对象的状态变化可以通知到其他对

随机推荐

  • Qt入门-下拉列表框QComboBox类

    QComboBox是QT GUI中的下拉列表框 class Q GUI EXPORT QComboBox public QWidget Q OBJECT 常用方法和属性 1 addItems void addItems const QStr
  • JavaWeb学习-02(response和request)

    JavaWeb学习 02 response和request 一 request对象 1 HttpServletRequest是ServletRequest的子接口 request对象用于接收客户端传递过来的请求内容 通过该对象的各种方法来获
  • weak_ptr 智能指针的使用

    目录 一 weak ptr 变量的定义 二 expired 成员函数 三 lock 成员函数 四 use count 成员函数 五 为什么要用 weak ptr 一 weak ptr 变量的定义 weak ptr 对象的构造有3种方法 1
  • 软件测试面试面对HR提出的问题,怎么回答才不会被面试官“套路”

    面试中 如何回答HR提出的问题很大程度上决定了面试能不能成功 下面是软件测试人员在面试过程中经常被问到的10个问题 告诉你怎么回答才不会被面试官套路 请你做一个自我介绍 误区 一般人回答这个问题过于平常 只说姓名 年龄 爱好 工作经验 这些
  • 深度学习中的优化算法之NAG

    之前在https blog csdn net fengbingchun article details 124648766 介绍过Momentum SGD 这里介绍下深度学习的另一种优化算法NAG NAG Nesterov Accelera
  • 【航模】凤凰模拟器安装

    固定翼飞手3 1 航模入门教程 凤凰模拟器的安装与初始设置 航模模拟器详细教程 到群里下载凤凰模拟器 并按照视频进行安装 群里的文件安装方式相比自己CSDN里面介绍的安装方式更省力 DirectX它能够自己进行安装 自己的天地飞6遥控器是右
  • 八、RSTP

    STP协议虽然能够解决环路问题 但是收敛速度慢 影响了用户通信质量 如果STP网络的拓扑结构频繁变化 网络也会频繁失去连通性 从而导致用户通信频繁中断 IEEE于2001年发布的802 1w标准定义了快速生成树协议RSTP Rapid Sp
  • spring硬骨头-----解决循环依赖问题

    目录 what spring中是如何解决循环依赖问题的 整体思路 spring中初始化时设置属性值的方法 set和构造的区别 那么三级缓存是怎么处理的呢 实现细节 总结 1 三级缓存解决循环依赖问题的关键是什么 为什么提前暴露对象能够解决
  • SpringBoot整合shiro-spring-boot-web-starter启动报错

    最近在做一个SpringBoot整合常用框架的系统 在整合Shiro时启动就报错 现将解决办法总结如下 SpringBoot使用的是最新的2 3 4版本 Shiro使用的是shiro spring boot web starter1 6 0
  • Python 数组操作指南:使用示例和方法解析

    什么是 Python 数组 数组是一种基本数据结构 也是大多数编程语言的重要组成部分 在 Python 中 它们是能够同时存储多个项目的容器 具体来说 它们是元素的有序集合 每个值都具有相同的数据类型 这是关于 Python 数组需要记住的
  • 11. 微积分 - 偏导数&方向导数

    文章目录 偏导数 方向导数 方向余弦 投影 继续讲方向导数 Hi 大家好 我是茶桁 我们上节课学习了链式法则 本节课 我们要学习 偏导数 和 方向导数 偏导数 偏导数在导论课里面也提到过 偏导数针对多元函数去讲的 多元函数是什么 我们拿个例
  • springboot 获取 property参数

    public class TankyxApiMemberApplication extends SpringBootServletInitializer public static void main String args Configu
  • 排列组合(递推矩阵)

    排列与组合有什么区别 排列与元素的顺序有关 组合与顺序无关 如何递推出对应的排列组合呢 组合 通过上面的组合公式可以得到下面的数据表格 n m 0 1 2 3 4 5 6 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 2
  • 单链表的基本操作c++

    头节点 第一个节点 一般不储存数据 头指针 指向第一个节点 首元节点 第一个储存数据的节点 可以通过头节点或头指针指向整个链表 链表的初始化 前插法 前插法 node initlink node p node malloc sizeof n
  • JavaSE 01

    JAVASE 学习1 作为初学者 主要在此记录学习过程中的点滴 以供参考和后期回顾 1 Java是一个全面且功能强大的语言 可用于多种用途 Java有三个版本 Java标准版 Java Standard Edition Java SE 可以
  • 手把手教你用VS2019搭建Linux开发环境

    因为linux的界面还是不如Windows友好 但是linux系统下可以看见一些更底层的东西 今天 我来教你用vs2019搭建linux项目 第一步 打开vs的安装器 看下面标注的组件是否安装 第二步 开启linux ssh服务 ubunt
  • Android Studio连接夜神模拟器

    Android Studio连接夜神模拟器 一 下载夜神模拟器 二 夜神模拟器连接Android Studio 三 其他操作 3 1 屏幕旋转 3 2 创建其他模拟器 一 下载夜神模拟器 官网 https www yeshen com 下载
  • TCP如何保证可靠传输

    TCP如何保证可靠传输 TCP保证可靠传输的方式有 校验和 序列号 确认应答 超时重传 连接管路 流量控制 拥塞控制等 1 校验和 在数据传输过程中 吧传输的数据当作一个16位整数 吧所有的数据加起来 最前面的进位补到最后一位 然后取反得到
  • 钱币兑换问题(dp背包)

    钱币兑换问题 在一个国家仅有1分 2分 3分硬币 将钱N兑换成硬币有很多种兑法 请你编程序计算出共有多少种兑法 Input 每行只有一个正整数N N小于32768 Output 对应每个输入 输出兑换方法数 Sample Input 293
  • 观察者模式(推模型+拉模型)

    观察者模式 Observer Pattern 当一个对象被修改时 会自动通知它的依赖对象 现在我们是新闻社 要向所有新闻订阅者推送新闻 那么该如何实现呢 经过思考我们不难发现一家新闻社一般对应的是多个新闻订阅者 那么我们先从新闻社开始入手