Rxjava源码解析笔记 | Rxjava概述 & 传统观察者设计模式源码解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: Rxjava源码解析笔记 | Rxjava概述 & 传统观察者设计模式源码解析

进行耗时任务

比如:在后台做一些网络操作、查询或者一些复杂计算的时候,
我们如果不用其他框架的话,
最常见做法即自己开一个子线程
然后通过回调的形式获取到结果(如后台以结果为参数发送广播,前台回调onReceive()接收获取到结果);

但是这样有一个问题,
随着业务逻辑越来越复杂,
项目会陷入回调中套回调的病区

这对后期维护代码来说是一个很严重的问题;


而Rxjava的出现解决了以上的问题

  • Rxjava本质上是一个异步操作库

它是一个能用非常简单的逻辑,去处理那些繁琐复杂任务
异步的操作事件库;
Rxjava在一定的程度上,

也能替代项目中非常多的Handler、AsyncTask等等;


关于Rxjava的设计模式——观察者模式

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

  • 在app开发中,如果有一个对象的状态/数据,是你非常要关心的,

同时你每个页面所有的UI都会跟这个对象绑定,
即当这个对象发生改变的时候,我们就需要通知所有的页面都去做UI改变;
以上所述其实便是一种观察者模式
**A对象对B对象的数据高度敏感,
当B对象变化的一瞬间,A对象要做出反应;
这时候A对象就是观察者,B对象就是被观察者;

观察者模式的情况,
就是众多的观察者,对被观察者的数据 高度敏感,
被观察者变化之后观察者自身的一种反应,
它是一种一对多的关系,多个观察者对应一个被观察者;**

  • 观察者模式的UML类图

    • Observerable(被观察者接口,interface):

      • registerObserver():将观察者注册到被观察者当中;即订阅方法;
      • removeObserver():将观察者从被观察者中移出;取消订阅方法;
      • notifyObservers():当我们被观察者状态改变的时候,这个方法就会被调用;

而此方法内部又会调用观察者接口(Observer)update()方法,
去通知观察者(Observer)做出相应的处理改变;

- ConcreteObserverable(被观察者具体的实现,class)
    - 实现了Observerable(被观察者接口,interface)定义的三个方法;
    - 定义了List<Observer>,用于保存注册好的观察者;

泛型是Observer,是接口,而非具体的实现类,
**这样做的原因就是,
为了让一个被观察者实例,
可以对应着,可能会有的,
多个实现了Observer(观察者)接口的观察者实现类,**
(一个被观察者实例可以对应多个观察者实现类实例
如此便可把观察者和被观察者通过List进行解耦

二来,泛型不指定具体的实现类,方便后续进行拓展,
即只要把拓展的观察者实现类去实现观察接口便合格,
由此可以实现各式各样的观察者;

- Observer(观察者接口)
    - 定义了```update()```方法;

当我们被观察者状态改变的时候,notifyObservers()方法就会被调用;
notifyObservers()内部则会调用本update()方法,
去通知观察者(Observer)做出相应的处理改变;

- ConcreteObserver(观察者实现类)

具体实现了Observer(观察者接口)的update()方法;

简单看一下观察者设计模式的代码

  • Observerable接口:
package com.example.jiajiemu.a11.observe;



/**
 * Created by Mjj on 2017/10/6.
 */

public interface Observerable {
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObservers();
}
  • Observer接口:
package com.example.jiajiemu.a11.observe;

/**
 * Created by Mjj on 2017/10/6.
 */

public interface Observer {
    public void update(int edition,float cost);
}
  • ConcreteObserverable实现类:
package com.example.jiajiemu.a11.observe;

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

/**
 * Created by Mjj on 2017/10/6.
 */

public class ConcreteObserverable implements Observerable {

    private List<Observer> mObservers;
    private int edition;
    private float cost;

    public ConcreteObserverable() {
        mObservers = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer o) {
        mObservers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        int i = mObservers.indexOf(o);
        if(i >= 0)
            mObservers.remove(i);
    }

    @Override
    public void notifyObservers() {
        for(int i = 0; i < mObservers.size(); i++){
            Observer observer = mObservers.get(i);
            observer.update(edition, cost);
        }
    }

    public void setInfomation(int edition,float cost){
        this.edition = edition;
        this.cost = cost;
        //信息更新完毕,通知所有观察者
        notifyObservers();
    }

}
  • .

    • notifyObservers()

可以看到方法中所写,遍历所有观察者,
依次使每一个观察者调用update()方法进行数据更新
update()方法在ConcreteObserver中具体实现):

    @Override
    public void notifyObservers() {
        for(int i = 0; i < mObservers.size(); i++){
            Observer observer = mObservers.get(i);
            observer.update(edition, cost);
        }
    }
  • ConcreteObserver实现类:
package com.example.jiajiemu.a11.observe;

/**
 * Created by Mjj on 2017/10/6.
 */

public class ConcreateObserver implements Observer {

    private String name;
    private int edition;
    private float cost;

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

    @Override
    public void update(int edition, float cost) {
        this.edition = edition;
        this.cost = cost;
        buy();
    }

    public void buy(){
        System.out.println(name+"购买了第"+edition+"期的杂志,花费了"+cost+"元。");
    }

}
  • .

    • 主要实现,

update()方法中添加的业务逻辑buy()方法,
buy()方法是可以根据不同场景做相应的逻辑判断,数据更新;
或者可以在update()方法中添加更多的业务逻辑

  • Client客户端测试类:
package com.example.jiajiemu.a11.observe;

/**
 * Created by Mjj on 2017/10/6.
 */

public class Client {
    public static void main(String[] args) {
        //创建被观察者
        ConcreteObserverable concreteObserverable = new ConcreteObserverable();

        //创建三个不同的观察者
        Observer observerA = new ConcreateObserver("A");
        Observer observerB = new ConcreateObserver("B");
        Observer observerC = new ConcreateObserver("C");

        //将观察者注册到被观察者中
        concreteObserverable.registerObserver(observerA);
        concreteObserverable.registerObserver(observerB);
        concreteObserverable.registerObserver(observerC);

        //更新被观察者中的数据,当数据更新后,会自动通知所有已注册的观察者
        concreteObserverable.setInfomation(5, 12);
    }

}
  • .

    - ```setInformation()```,封装了一下```notifyObservers()```:
@Override
    public void notifyObservers() {
        for(int i = 0; i < mObservers.size(); i++){
            Observer observer = mObservers.get(i);
            observer.update(edition, cost);
        }
    }

    public void setInfomation(int edition,float cost){
        this.edition = edition;
        this.cost = cost;
        //信息更新完毕,通知所有观察者
        notifyObservers();
    }

传统观察者模式的使用场景

1.一个方面的操作/处理依赖于另一个方面的状态变化
(即观察者的操作依赖于被观察者的状态变化;
埋伏中的警察的操作依赖于小偷的状态变化,
球迷的操作依赖于球赛的状态变化)

  1. **如果在更改一个对象的时候,

需要同时连带改变其他的对象;**

  1. **当一个对象必须通知其他的对象,

但是你又希望这个对象和其他被通知的对象是松散耦合的;**




参考自 慕课网

相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
76 2
|
24天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
51 12
|
19天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
1月前
|
存储 网络协议 算法
OSPF中的Link-State Database (LSDB): 概述与深入解析
OSPF中的Link-State Database (LSDB): 概述与深入解析
147 1
|
1月前
|
存储 安全 Linux
Golang的GMP调度模型与源码解析
【11月更文挑战第11天】GMP 调度模型是 Go 语言运行时系统的核心部分,用于高效管理和调度大量协程(goroutine)。它通过少量的操作系统线程(M)和逻辑处理器(P)来调度大量的轻量级协程(G),从而实现高性能的并发处理。GMP 模型通过本地队列和全局队列来减少锁竞争,提高调度效率。在 Go 源码中,`runtime.h` 文件定义了关键数据结构,`schedule()` 和 `findrunnable()` 函数实现了核心调度逻辑。通过深入研究 GMP 模型,可以更好地理解 Go 语言的并发机制。
|
1月前
|
消息中间件 缓存 安全
Future与FutureTask源码解析,接口阻塞问题及解决方案
【11月更文挑战第5天】在Java开发中,多线程编程是提高系统并发性能和资源利用率的重要手段。然而,多线程编程也带来了诸如线程安全、死锁、接口阻塞等一系列复杂问题。本文将深度剖析多线程优化技巧、Future与FutureTask的源码、接口阻塞问题及解决方案,并通过具体业务场景和Java代码示例进行实战演示。
54 3
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
1月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
1月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式

推荐镜像

更多