Android开发之设计模式-观察者模式

观察者模式(Observer Pattern)

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

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决:使用面向对象技术,可以将这种依赖关系弱化。

关键代码:在抽象类里有一个 ArrayList 存放观察者们。

应用实例: 1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。 2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。

优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景:

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项: 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

观察者模式可以说用的比较多,比如天气预报服务,你订阅了本地的天气,每天一旦天气信息更新,它就会及时发送最新的天气信息。再比如,杂志的订阅,你只需向邮局订阅杂志,缴纳一定的费用,当有新的杂志时,邮局会自动将杂志送至你预留的地址。

以上例子有一个共同点,就是我们无需每时每刻关注我们感兴趣的东西,我们只需做的就是订阅感兴趣的事物,比如天气预报服务,杂志等,一旦我们订阅的事物发生变化,比如有新的天气预报信息,新的杂志等,被订阅的事物就会即时通知到订阅者,即我们。而这些被订阅的事物可以拥有多个订阅者,也就是一对多的关系。当然,严格意义上讲,这个一对多可以包含一对一,因为一对一是一对多的特例。

现在你反过头来看看观察者模式的定义,你是不是豁然开朗了。

观察者,我们称它为Observer,有时候我们也称它为订阅者,即Subscriber

被观察者,我们称它为Observable,即可以被观察的东西,有时候还会称之为主题,即Subject

实例:

1、定义一个Weather实体类

public class Weather {//天气实体类
    private String description;
    public Weather(String description){
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "Weather{" +
                "description='" + description + '\'' +
                '}';
    }
}

2、定义观察者

我们想要这个被观察者能够通用,将其定义成泛型。内部应该暴露register和unregister方法供观察者订阅和取消订阅,至于观察者的保存,直接用ArrayList即可,此外,当有主题内容发送改变时,会即时通知观察者做出反应,因此应该暴露一个notifyObservers方法,以上方法的具体实现见如下代码。

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

public class Observable <T>{

    List<Observer<T>> mObservers = new ArrayList<Observer<T>>();
    public void register(Observer<T> observer){
        if (observer == null){
            throw new NullPointerException("observer == null");
        }
        synchronized (this){
            if(!mObservers.contains(observer)){
                mObservers.add(observer);
            }
        }
    }

    public synchronized void unregister(Observer<T> observer){
        mObservers.remove(observer);
    }
    public void notifyObserver(T data){
        for (Observer<T> observer:mObservers) {
            observer.onUpdate( this,data);
        }
    }
}

3、我们的观察者,只需要实现一个观察者的接口Observer,该接口也是泛型的。其定义如下

public interface Observer<T> {
    void onUpdate(Observable<T> observable,T data);
}

一旦订阅的主题发送变换就会回调该接口。

我们来使用一下,我们定义了一个天气变换的主题,也就是被观察者,还有两个观察者观察天气变换,一旦变换了,就打印出天气信息,注意一定要调用被观察者的register进行注册,否则会收不到变换信息。而一旦不敢兴趣了,直接调用unregister方法进行取消注册即可

public class Main {
    public static void main(String[] args) {
        Observable<Weather> observable = new Observable<Weather>();
        Observer<Weather> observer1 = new Observer<Weather>() {
            @Override
            public void onUpdate(Observable<Weather> observable, Weather data) {
                System.out.println("观察者1 :" +data.toString());
            }
        };
        Observer <Weather> observer2 = new Observer<Weather>() {
            @Override
            public void onUpdate(Observable<Weather> observable, Weather data) {
                System.out.println("观察者2 :" +data.toString());
            }
        };

        observable.register(observer1);
        observable.register(observer2);

        Weather weather=new Weather("晴转多云");
        observable.notifyObserver(weather);

        Weather weather1=new Weather("多云转阴");
        observable.notifyObserver(weather1);

        observable.unregister(observer1);

        Weather weather2=new Weather("台风");
        observable.notifyObserver(weather2);


    }
}

输出结果:

《Android开发之设计模式-观察者模式》

EventBus中的观察者模式:观察者模式的三个典型方法它都具有,即注册,取消注册,发送事件

EventBus.getDefault().register(Object subscriber);
EventBus.getDefault().unregister(Object subscriber);

EventBus.getDefault().post(Object event);

RxJava

创建一个被观察者

Observable<String> myObservable = Observable.create(  
    new Observable.OnSubscribe<String>() {  
        @Override  
        public void call(Subscriber<? super String> sub) {  
            sub.onNext("Hello, world!");  
            sub.onCompleted();  
        }  
    }  
);

创建一个观察者,也就是订阅者

Subscriber<String> mySubscriber = new Subscriber<String>() {  
    @Override  
    public void onNext(String s) { System.out.println(s); }  
  
    @Override  
    public void onCompleted() { }  
  
    @Override  
    public void onError(Throwable e) { }  
};

观察者进行事件的订阅

myObservable.subscribe(mySubscriber);

以上既为观察者模式的简介,详解见链接:

https://wenku.baidu.com/view/662028d0360cba1aa811da52.html?st=1

 观察者模式在Android中被应用的很是频繁,包括一些优秀的开源框架都会用到,下篇我们开始学习一些Android中常用的一些开源框架,学习下其中的核心思想,看懂别人的代码到运用别人的代码,再到优化别人的代码,这段路程还很长,还需要很多的努力。

待续…

    原文作者:yun382657988
    原文地址: https://blog.csdn.net/yun382657988/article/details/82998020
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞