美文网首页
第三方开源库学习

第三方开源库学习

作者: 日落_3d9f | 来源:发表于2021-01-24 10:32 被阅读0次

    视频地址:Android第三方库开源框架详解合集(含热修复、插件化、组件化等)

    热修复 补丁包

    学习1-2

    35. 观察者模式详解

    Rxjava 验证用户登录步骤

    响应式思想:在整个业务链内,前面的步骤都会对后面产生影响。响应式编程思想解决以上线式流程的问题,避免if...else等混乱代码和思维。

    观察者模式

    首先理解一下观察者模式的定义:

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

    直译:

    建立一个一(Subject)对多(Observer)的关系,能够使得当"一"变化的时候,依赖这个"一"的多也能够同步改变。

    观察者模式所涉及的角色有:

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

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

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

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

    以上就是观察者模式的基本内容,现在要开始写一个观察者模式的代码前,请先检查下我们的“武器”:

    在JAVA语言的API中,提供了一个Observable抽象类以及一个Observer接口,构成JAVA语言对观察者模式的支持。

    1. Observable抽象类 抽象主题角色,具体主题类必须继承该抽象类,同时抽象主题提供一个接口可以增加和删除观察者对象以及一个消息通知方法。
    2. Observer接口类,抽象观察者角色,具体观察者必须实现该接口,同时它定义了一个更新接口,具体观察者必须实现该更新方法。

    观察者模式需要用到的Java类

    1 java.util.Observable

    -able一般可能...的单词后缀,Observable就是可以被观察的,程序中的被观察者类,需要继承这个类。

    2 java.util.Observer

    这个是观察者,是接口。程序中的观察者类,需要实现这个接口中的update()方法。

    下面开始讲解观察者模式的JAVA Demo:

    (1)观察者对象User 一个接口类,必须实现update方法(获取更新消息)。User类相当于上图中的具体的观察者。

    package com.egastech;
    
    import java.util.Observable;
    import java.util.Observer;
    
    public class User implements Observer{
        private String name;
        public User(String name){
            this.name = name;
        }
    
        @Override
        public void update(Observable o, Object arg) {
            // TODO Auto-generated method stub
            System.out.println("微信用户:"+name+",您的微信公众号更新这些内容:"+arg);
        }
    }
    

    (2)被观察者对象WeChatServer ,需要重写一个消息通知方法(publishnewInfo)。相当于一个具体的被观察者。

    /*
     * WeChatServer 是具体被观察的对象:
     *     当它更新时,所有监听该对象的观察者(微信用户)都会接收到通知
     * */
    package com.egastech;
    
    import java.util.Observable;
    
    public class WeChatServer extends Observable {
    
        /**
         *
         * @param info  要给观察者的信息
         */
        public void publishNewInfo(String info){
            //标识这个Observable对象已经改变了,更具体来将就是把Observable中属性changed置为true.
            setChanged();
            //在通知所有观察者之前,需要判断Observable中属性changed是否为true,如若不为则不会发出通知。
            //具体可以看源码,蛮好理解的。
            notifyObservers(info);
        }
    }
    

    (3)测试主类

    package com.egastech;
    
    public class Test {
    
        public static void main(String[] args) {
    
            //被观察的角色
            OfficialAccount officialAccount = new WeChatServer();
    
            //观察者
            User userBob = new User("WeChat User-Bob");
            User userTom = new User("WeChat User-Tom");
            User userMe = new User("WeChat User-Me");
    
            //将观察者注册到可观察对象的观察者列表中
            officialAccount.addObserver(userBob);
            officialAccount.addObserver(userTom);
            officialAccount.addObserver(userMe);
    
            //发布消息
            officialAccount.publishNewInfo("...新内容...");
            officialAccount.deleteObserver(userMe);
            System.out.println("##########################################");
            officialAccount.publishNewInfo("...新内容123...");
    
        }
    }
    

    测试结果:
    添加三个监听者,三个监听者都可以收到消息,删除掉一个监听者,只有剩下两个监听者可以收到消息。

    User是具体的观察者,他们订阅了OfficialAccount这个具体的可观察对象,当OfficialAccount有更新时,会遍历所有观察者。然后给这些观察者发布一个更新消息,之后User中的update方法会调用,这样就达到了一对多的通知功能。

    微信用户:WeChat User-Me,您的微信公众号更新这些内容:...新内容...
    微信用户:WeChat User-Tom,您的微信公众号更新这些内容:...新内容...
    微信用户:WeChat User-Bob,您的微信公众号更新这些内容:...新内容...
    ##########################################
    微信用户:WeChat User-Tom,您的微信公众号更新这些内容:...新内容123...
    微信用户:WeChat User-Bob,您的微信公众号更新这些内容:...新内容123...
    

    36. 观察者模式如何修改成链式结构

    抽象的观察者:

    package com.egastech.second;
    
    /*
     * 抽象的观察者
     */
    public interface Observer<T> {
        //用于订阅成功的回调
        void onSubscribe();
        //update 收到消息
        void onNext(T t);
        //出错的回应
        void onError(Throwable e);
        //从订阅到信息发送全部完成
        void onComplete();
    }
    
    

    抽象的被观察者:

    package com.egastech.second;
    
    /*
     * 抽象的被观察者
     */
    public interface ObservableSource<T> {
        //notify将给定的observer订阅功能订阅出来
        void subscribe(Observer<T> observer);
    }
    

    具体的被观察者:

    package com.egastech.second;
    
    //具体的被观察者
    public abstract class Observable<T> implements ObservableSource {
        @Override
        public void subscribe(Observer observer) {
            //我们把整个订阅的功能让子类来完成
            subscribeActual(observer);
        }
    
        protected abstract void subscribeActual(Observer<T> observer);
    
        //创造被观察者的实例
        public static<T> Observable<T> create(ObservableOnSubscribe<T> source) {
            return new ObservableCreate(source);
        }
    }
    
    

    用来创建被观察者对象:

    package com.egastech.second;
    
    /*
     * 用来创建被观察者对象
     */
    public class ObservableCreate<T> extends Observable {
    
        ObservableOnSubscribe<T> source;
    
    
        public ObservableCreate(ObservableOnSubscribe<T> source) {
            this.source = source;
        }
    
        public ObservableCreate() {
        }
    
        @Override
        public void subscribe(Observer observer) {
            super.subscribe(observer);
        }
    
        @Override
        protected void subscribeActual(Observer observer) {
            //如果订阅功能要实现,在这里就应该通知Observer消息更新了
            //调用observer.onNext(observer);等方法
            CreateEmitter<T> parent = new CreateEmitter<T>(observer);
            observer.onSubscribe();
            //把发射器和被观察者绑定在一起,完成一个订阅
            source.subscribe(parent);
    
        }
    
        static final class CreateEmitter<T> implements Emitter<T> {
            Observer<T> observer;
            public CreateEmitter(Observer<T> observer) {
                this.observer = observer;
            }
    
            @Override
            public void onNext(T t) {
                observer.onNext(t);
            }
    
            @Override
            public void onError(Throwable t) {
                observer.onError(t);
            }
    
            @Override
            public void onComplete(T t) {
                observer.onComplete();
            }
        }
    }
    

    为每一个订阅的观察者提供一个能进行消息发送的功能:

    package com.egastech.second;
    
    public interface ObservableOnSubscribe<T> {
        //为每一个订阅的观察者提供一个能进行消息发送的功能
        void subscribe(Emitter<T> emitter);
    }
    

    定义了发送消息的API:

    package com.egastech.second;
    
    /*
     * 定义了发送消息的API
     */
    public interface Emitter<T> {
        //发送消息
        void onNext(T t);
        //发送异常
        void onError(Throwable t);
        //发送完成的信号
        void onComplete(T t);
    }
    

    测试结果:

    package com.egastech.second;
    
    public class Example {
        public static void main(String[] args) {
            Observable.create(new ObservableOnSubscribe<String>() {
    
                @Override
                public void subscribe(Emitter<String> emitter) {
                    emitter.onNext("大家好");
                }
            }).subscribe(new Observer() {
                @Override
                public void onSubscribe() {
    
                }
    
                @Override
                public void onNext(Object o) {
                    System.out.println("收到消息 [" + (String) o + "]");
                }
    
                @Override
                public void onError(Throwable e) {
    
                }
    
                @Override
                public void onComplete() {
    
                }
            });
        }
    }
    

    执行结果:

    com.egastech.second.Example
    收到消息 [大家好]
    

    注:Rxjava是事件订阅的时候就执行触发事件,可以说是订阅一下触发一次;Rxjava其实在事件消费的时机上与传统的观察者模式有所不同。传统观察者模式都是在所有事件订阅完成之后,发出信号而后所有订阅者统一收到同一份事件,而Rxjava则是订阅即触发单独的事件消费。

    原来是被观察者直接通知观察者:


    被观察者直接通知观察者
    被观察者直接通知观察者

    现在单独写了一个类ObservableOnSubscribe,负责将Emitter绑定到Observer,通过发射器通知观察者。


    ObservableOnSubscribe版本
    image.png

    相关文章

      网友评论

          本文标题:第三方开源库学习

          本文链接:https://www.haomeiwen.com/subject/fxkuzktx.html