观察者模式,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变,所有依赖于它的对象都能得到通知并可以自动作出处理
比如说:报纸的订阅,一旦订阅,当有新的报纸发布,所有的订阅者都会收到消息
基本概念 组成
观察者:Observer,也叫订阅者,即Subscriber(Rxjava)
被观察者:Observable
java中的体现 java中提供了Observable 和Observe 接口供我们快速实现这种模式
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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 + '\'' + '}' ; } }
定义观察者接口(因为观察者可能有很多类型,所以我们定义成一个接口,如果想要订阅这个事件,实现这个接口即可,另外一般订阅之后,在实现接口中的方法的参数中会拿到发布的数据,数据的类型不固定所以这个观察者接口需要定义范型)
1 2 3 public interface Observer <T > { void onUpdate (Observable<T> observable,T data) ; }
定义被观察者对象(可以设计成单例模式,类似EventBus,内部维持一个集合,用来保存观察者对象;register方法和unregister方法用来将观察者对象从集合中添加和移除出来,post方法用来发布,循环遍历集合,依次调用观察者的相关回调方法,并将发布的参数传入)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package com.it.fengan.designpattern.pattern;import java.util.ArrayList;import java.util.List;public class Observable <T > { private static Observable observable; private Observable () { } public static Observable getInstance () { if (observable == null ) { synchronized (Observable.class) { if (observable == null ) { observable = new Observable(); } } } return observable; } private List<Observer> observers = new ArrayList<>(); public void register (Observer<T> observer) { if (observer == null ) { throw new RuntimeException("observer error" ); } synchronized (Observable.class) { if (!observers.contains(observer)) { observers.add(observer); } } } public void unregister (Observer<T> observer) { observers.remove(observer); } public void post (T data) { for (Observer observer : observers) { observer.onUpdate(this , data); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Test public void testObserver () { Observer<Weather> objectObserver1 = new Observer<Weather>(){ @Override public void onUpdate (Observable<Weather> observable, Weather data) { Log.e("testObserver" , "objectObserver1:data=" + data.toString()); } }; Observer<Weather> objectObserver2 = new Observer<Weather>(){ @Override public void onUpdate (Observable<Weather> observable, Weather data) { Log.e("testObserver" , "objectObserver2:data=" + data.toString()); } }; Observable observable = Observable.getInstance(); observable.register(objectObserver1); observable.register(objectObserver2); Weather weather = new Weather("晴天" ); observable.post(weather); observable.unregister(objectObserver2); observable.post(weather); }
logcat输出
1 2 3 12 -19 15 :18 :44.780 2004 -2036 /? E/ testObserver: objectObserver1: data=Weather{description='晴天' }12 -19 15 :18 :44.780 2004 -2036 /? E/ testObserver: objectObserver2: data=Weather{description='晴天' }12 -19 15 :18 :44.780 2004 -2036 /? E/ testObserver: objectObserver1: data=Weather{description='晴天' }
Android中的应用
1 2 3 4 5 6 7 Button btn=new Button(this ); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { Log.e("TAG" ,"click" ); } });
只要是set系列的设置监听器的方法最多都只能算回调,但是有一些监听器式add进去的,这种就是观察者模式了(比如RecyclerView中的addOnScrollListener方法)
RecycleView.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 private List<OnScrollListener> mScrollListeners;public void addOnScrollListener (OnScrollListener listener) { if (mScrollListeners == null ) { mScrollListeners = new ArrayList<>(); } mScrollListeners.add(listener); } public void removeOnScrollListener (OnScrollListener listener) { if (mScrollListeners != null ) { mScrollListeners.remove(listener); } } public void clearOnScrollListeners () { if (mScrollListeners != null ) { mScrollListeners.clear(); } }
Android的广播机制,其本质也是观察者模式,这里为了简单方便,直接拿本地广播的代码说明,即LocalBroadcastManager
1 2 3 4 LocalBroadcastManager localBroadcastManager=LocalBroadcastManager.getInstance(this ); localBroadcastManager.registerReceiver(BroadcastReceiver receiver, IntentFilter filter); localBroadcastManager.unregisterReceiver(BroadcastReceiver receiver); localBroadcastManager.sendBroadcast(Intent intent)
观察者模式的三个典型方法它都具有,即注册,取消注册,发送事件
1 2 3 4 EventBus.getDefault().register(Object subscriber); EventBus.getDefault().unregister(Object subscriber); EventBus.getDefault().post(Object event);
创建一个被观察者
1 2 3 4 5 6 7 8 9 Observable<String> myObservable = Observable.create( new Observable.OnSubscribe<String>() { @Override public void call (Subscriber<? super String> sub) { sub.onNext("Hello, world!" ); sub.onCompleted(); } } );
创建一个观察者,也就是订阅者
1 2 3 4 5 6 7 8 9 10 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) { } };
观察者进行事件的订阅
1 myObservable.subscribe(mySubscriber);