RxJava的前世【RxJava系列之设计模式】

一. 前言

学习RxJava,少不了介绍它的设计模式。但我看大部分文章,都是先将其用法介绍一通,然后再结合其用法,讲解其设计模式。这样当然有很多好处,但我个人觉得,这种介绍方式,对于没有接触过RxJava的朋友来说,是不太友好的。

而我,更倾向于,先把对设计模式的认知,拉齐,然后在讲到用法的时候,大家就会自然而然地理解了它怎么用到的设计模式,从而也就更容易理解源码了,一切都是水到渠成。

所以,在本篇文章中,大部分内容依然不会涉及RxJava,但其实处处都有RxJava的影子。你需要做的就是完全理解本篇文章的内容,没有理解到的地方请留言,我都会一个一个认真看的。
不啰嗦了,让我们开始正题吧!

二. 观察者模式

1. 什么是观察者模式?

一个比较书面化的定义是:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

通俗一点理解,假如说有两种对象,一个是观察者,一个是被观察者,当一个被观察者对象发生变化的时候,可以通知到所有的观察者对象。所有的观察者对象在接收到这个通知的时候,可以做一些自己的处理。

2. Android中有没有例子?

在Android中,观察者模式其实很常见,比如点击事件监听,当view被点击的时候,会通知到它的观察者,也就是调用到你实现的onClick方法。再比如说EventBus,比如LiveData,其实都有运用到观察者模式。

3. 写个代码?

本着KISS原则(Keep It Simple, Stupid),观察者模式比较简单,所以在这里,就不写代码了。
但值得一提的是,RxJava中运用到的观察者模式,和这里有一点微小的差别,但根本思想是一样的。至于是什么微小的差别,等讲到RxJava原理的时候,你就理解了。

三. 装饰器模式

1. 什么是装饰器模式?

可以通俗地理解为,在不改变原有对象的基础上,增强原有对象的功能。

2. Android中有没有例子?

我们天天接触的Context,就是一个非常典型的装饰器模式的例子。

Android中的Context对象是一个核心的组件,它经常被装饰器进行功能扩展和定制。例如,Activity、Service、BroadcastReceiver等都是Context的子类,它们在基本的Context功能上添加了更多的生命周期管理、界面交互和事件处理等功能。

相当于在没有修改Context的基础上,对Context进行了功能的增强。

3. 写个代码?

因为我们平时关于装饰器模式,写的不是很多,所以我觉得有必要,以一个很简单的例子,向大家再进一步介绍下装饰器模式。
假设你经营一家咖啡店,你的顾客可以根据自己的口味定制咖啡。首先,我们有一个抽象的咖啡接口

public interface Coffee {String getDescription();double getCost();
}

然后,我们还有一个具体的咖啡实现

public class SimpleCoffee implements Coffee {@Overridepublic String getDescription() {return "Simple Coffee";}@Overridepublic double getCost() {return 1.0;}
}

现在,我们不满足于一个简单的咖啡(SimpleCoffee),而是要有一个可以加入牛奶的咖啡。相当于对原有的咖啡功能进行增强,这时,我们就可以借助装饰器模式来实现。
首先,声明一个装饰器模式的抽象类,也实现Coffee接口。

public abstract class CoffeeDecorator implements Coffee {protected Coffee coffee;public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic String getDescription() {return coffee.getDescription();}@Overridepublic double getCost() {return coffee.getCost();}
}

然后,可以创建一个具体的装饰器类

public class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return super.getDescription() + ", Milk";}@Overridepublic double getCost() {return super.getCost() + 0.5;}
}

这样我们在使用的时候,顾客可以选择加入咖啡,而不会改变原有的咖啡类

Coffee simpleCoffee = new SimpleCoffee();
Coffee coffeeWithMilk = new MilkDecorator(simpleCoffee);
System.out.println(coffeeWithMilk.getDescription());  // 输出:Simple Coffee, Milk
System.out.println(coffeeWithMilk.getCost());  // 输出:1.5

为什么实现了同一个接口?

这里大家也会发现一个细节,就是装饰器类,和被装饰类,都实现了同一个接口,在这个例子中就是Coffee接口。这样做的好处就是可以统一以Coffee来接收装饰器类和被装饰类,这使得客户端可以根据需求自由组合装饰器对象,以获得所需的功能组合,方便多次嵌套,自己可以作为装饰器类,也可以作为被装饰类,实现更灵活,符合“基于接口而非实现”的规范。

举个例子,假如客户还想加糖,那么就可以新增一个加糖的装饰器类

public class SugerDecorator extends CoffeeDecorator {public SugerDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return super.getDescription() + ", Suger";}@Overridepublic double getCost() {return super.getCost() + 0.3;}
}

然后顾客如果既想加糖,又想加牛奶,就可以这样实现:

Coffee simpleCoffee = new SimpleCoffee();
Coffee coffeeWithMilk = new MilkDecorator(simpleCoffee);
Coffee coffeeWithSuger = new SugerDecorator(coffeeWithMilk);

可以看到,MilkDecorator本身既是装饰器类,也是被装饰类,使得原有对象的功能,可以定制化地增强。而能够实现这些的原因,就是装饰器类和被装饰类,实现了同一个接口

四. 总结

本篇文章内容就到这里了,其实本篇文章没有提到RxJava的具体知识,但其实处处都有RxJava的影子。在本篇文章中,你只需要牢牢掌握观察者模式和装饰器模式,理解我举的例子,就可以了。等看到RxJava的原理的文章时,你就会豁然开朗!

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 使用QLabel的派生类实现QLabel的双击响应

1 介绍 在QLabel中没有双击等事件响应,需要构建其派生类,自定义信号(signals)、重载事件函数(event),最后在Qwidget中使用connect链接即可,进而实现响应功能。 对于其余没有需求事件响应的QObject同样适用。 此外,该功…

【HDFS】客户端读某个块时,如何对块的各个副本进行网络距离排序?

本文包含如下内容: ① 通过图解+源码分析/A1/B1/node1和 /A1/B2/node2 这两个节点的网络距离怎么算出来的 ② 客户端读文件时,副本的优先级。(怎么排序的,排序规则都有哪些?) ③ 我们集群发现的一个问题。 客户端读时,通过调用getBlockLocations RPC 获取文件的各个块。…

spring框架自带的http工具RestTemplate用法

1. RestTemplate是什么? RestTemplate是由Spring框架提供的一个可用于应用中调用rest服务的类它简化了与http服务的通信方式。 RestTemplate是一个执行HTTP请求的同步阻塞式工具类,它仅仅只是在 HTTP 客户端库(例如 JDK HttpURLConnection&a…

python 相关框架事务开启方式

前言 对于框架而言,各式API接口少不了伴随着事务的场景,下面就列举常用框架的事务开启方法 一、Django import traceback from django.db import transaction from django.contrib.auth.models import User try:with transaction.atomic(): # 在with…

利用appium抓取app中的信息

一、appium简介 二、appium环境安装 三、联调测试环境 四、利用appium自动控制移动设备并提取数据

nginx location的执行规则和root/alias的区分

nginx location的执行规则和root/alias的区分 总结 看本篇文章不是教如何从0编写nginx配置,而是看懂已存在的nginx配置。 官方文档定义:location [ | ~ | ~* | ^~ ] uri { … } :严格匹配,且匹配成功则不继续往下,优…

【openGauss】分区表的介绍与使用

一、openGauss分区表介绍 在openGauss中,数据分区是在一个节点内部对数据按照用户指定的策略做进一步的水平分表,将表中的数据按照指定方式划分为多个互不重叠的部分。 对于大多数用户使用场景,分区表和普通表相比具有以下优点: …

年轻代频繁GC ParNew导致http变慢

背景介绍 某日下午大约四点多,接到合作方消息,线上环境,我这边维护的某http服务突然大量超时(对方超时时间设置为300ms),我迅速到鹰眼平台开启采样,发现该服务平均QPS到了120左右,平…

希尔排序——C语言andPython

前言 步骤 代码 C语言 Python 总结 前言 希尔排序(Shell Sort)是一种改进的插入排序算法,它通过将数组分成多个子序列进行排序,逐步减小子序列的长度,最终完成整个数组的排序。希尔排序的核心思想是通过排序较远距…

SQL server 异地备份数据库

异地备份数据库 1.备份服务器中设置共享文件夹 2.源服务器数据库中添加异地备份代理作业 EXEC sp_configure show advanced options, 1;RECONFIGURE; EXEC sp_configure xp_cmdshell, 1;RECONFIGURE; declare machine nvarchar(50) 192.168.11.10 --服务器IP declare pa…

中科驭数亮相DPU峰会,分享HADOS软件生态实践和大数据计算方案,再获评“匠芯技术奖”

又是一年相逢时,8月4日,第三届DPU峰会在北京开幕,本届峰会由中国通信学会指导,江苏省未来网络创新研究院主办,SDNLAB社区承办,以“智驱创新芯动未来”为主题,沿袭技术创新、生态协同的共创效应&…

Vue-1.零基础学习Vue

当你从零开始学习 Vue.js 时,以下步骤可以帮助你系统地学习这个前端框架: 了解前端基础: 如果你对前端开发还不熟悉,可以先了解 HTML、CSS 和 JavaScript 的基础知识。这将为学习 Vue.js 奠定基础。 Vue.js 官方文档&#xff1…

【打印整数二进制的奇数位和偶数位】

打印整数二进制的奇数位和偶数位 1.题目 获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列 2.题目分析 打印一个整数的二进制位中的偶数位和奇数位,可以对整数进行移位操作,再将移位的二进制位与1进行&操作。 按位&a…

word将mathtype公式批量转为latex公式

最近,由于工作学习需要,要将word里面的mathype公式转为latex公式。 查了查资料,有alt\的操作,这样太慢了。通过下面链接的操作,结合起来可以解决问题。 某乎:https://www.zhihu.com/question/532353646 csd…

基于BNC和RTKLIB的GNSS组件包-星历设计

星历模块 主要包括如下:星历本身的数据结构,星历的编码解码和 rinex格式的文件读写等功能 星历分析工具主要包括:对应卫星更新 每个卫星星历的健康标记序列,星历的位置序列图 各个模块的组件图: class Eph { public:…

datePicker一个或多个日期组件,如何快捷选择多个日期(时间段)

elementUI的组件文档中没有详细说明type"dates"如何快捷选择一个时间段的日期&#xff0c;我们可以通过picker-options参数来设置快捷选择&#xff1a; <div class"block"><span class"demonstration">多个日期</span><el…

【Azure】office365邮箱测试的邮箱账号因频繁连接邮箱服务器而被限制连接 引起邮箱显示异常

azure微软office365邮箱会对频繁连接自身邮箱服务器的IP地址进行&#xff0c;连接邮箱服务器IP限制&#xff0c;也就是黑名单&#xff0c;释放时间不确定&#xff0c;但至少一天及以上。 解决办法&#xff0c;换一个IP&#xff0c;或者新注册一个office365邮箱再重试。 以下是…

Java课题笔记~ AspectJ 对 AOP 的实现(掌握)

AspectJ 对 AOP 的实现(掌握) 对于 AOP 这种编程思想&#xff0c;很多框架都进行了实现。Spring 就是其中之一&#xff0c;可以完成面向切面编程。然而&#xff0c;AspectJ 也实现了 AOP 的功能&#xff0c;且其实现方式更为简捷&#xff0c;使用更为方便&#xff0c;而且还支…

JVM 类加载和垃圾回收

JVM 1. 类加载1.1 类加载过程1.2 双亲委派模型 2. 垃圾回收机制2.1 死亡对象的判断算法2.2 垃圾回收算法 1. 类加载 1.1 类加载过程 对应一个类来说, 它的生命周期是这样的: 其中前 5 步是固定的顺序并且也是类加载的过程&#xff0c;其中中间的 3 步我们都属于连接&#xf…

用node.js搭建一个视频推流服务

由于业务中有不少视频使用的场景&#xff0c;今天来说说如何使用node完成一个视频推流服务。 先看看效果&#xff1a; 这里的播放的视频是一个多个Partial Content组合起来的&#xff0c;每个Partial Content大小是1M。 一&#xff0c;项目搭建 &#xff08;1&#xff09;初…