SuperObservable
其實android源碼里已經(jīng)有觀察者模式的封裝了:
package android.database;
import java.util.ArrayList;
public abstract class Observable<T> {
protected final ArrayList<T> mObservers = new ArrayList<T>();
public void registerObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
if (mObservers.contains(observer)) {
throw new IllegalStateException("Observer " + observer + " is already registered.");
}
mObservers.add(observer);
}
}
public void unregisterObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
int index = mObservers.indexOf(observer);
if (index == -1) {
throw new IllegalStateException("Observer " + observer + " was not registered.");
}
mObservers.remove(index);
}
}
public void unregisterAll() {
synchronized(mObservers) {
mObservers.clear();
}
}
}
可以看到這是一個抽象類,主要提供了三個方法,用來注冊和注銷觀察者。使用起來就是繼承Observable,然后添加一些notify的方法來通知觀察者。DataSetObservable就是這么做的:
package android.database;
public class DataSetObservable extends Observable<DataSetObserver> {
public void notifyChanged() {
synchronized(mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
public void notifyInvalidated() {
synchronized (mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onInvalidated();
}
}
}
}
但是我也學著DataSetObservable這么用了一段時間,發(fā)現(xiàn)太麻煩了,

1488458379147.jpg
每次都要寫一個類繼承Observable,而且要要調(diào)用里面的方法都要寫一段像
synchronized (mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onInvalidated();
}
}
這樣的代碼,還有一個局限性就是傳參,都要在notify里寫一遍,所以勢必要封裝一下。
不用每次寫一個類繼承Observable
-
不用在調(diào)用Observer里的方法時都寫一個notify方法
順著這個思路就是要 抽象類似mObservers.get(i).onChanged();的方法。
于是便寫了一個接口,拿到了observer想干什么就干什么。
public interface Dispatcher<T> {
void call(T t);
}
SuperObservale類誕生了:
public class SuperObservable<T> extends Observable<T> {
public void notifyMethod(Dispatcher<T> dispatcher){
synchronized (mObservers){
for (int i = mObservers.size()-1; i >= 0; i--) {
T t = mObservers.get(i);
if(dispatcher!=null){
dispatcher.call(t);
}
}
}
}
}
}
這樣只要在disatcher里寫好要調(diào)用的方法,就可以notify T(觀察者)中的任何方法了。每次只要new SuperObservable<T>便創(chuàng)建了一個被觀察者,簡單了不少。
考慮到有一個項目中會用到多次觀察者模式,便寫了一個SuperObservable的管理類:
public class SuperObservableManager {
private static SuperObservableManager instance;
private HashMap<Class,SuperObservable> mObservables;
private SuperObservableManager() {
mObservables = new HashMap<>();
}
public static SuperObservableManager getInstance(){
if(instance==null){
synchronized (SuperObservableManager.class){
if(instance==null){
instance = new SuperObservableManager();
}
}
}
return instance;
}
/**
* 添加被觀察者
* @param observableName
* @param superObservable
* @param <Observer>
* 利用泛型約束被觀察者superObservable:
* 讓其只受Observer類型的觀察者觀察
*/
public <Observer> void addObservable(Class<Observer>observableName,SuperObservable<Observer>superObservable){
if(mObservables.containsKey(observableName)){
throw new IllegalStateException("已添加過"+observableName.getSimpleName()+"類型的被觀察者!");
}
mObservables.put(observableName,superObservable);
}
/**
* 獲取被觀察者
* @param observableName
* @return
*/
public <Observer> SuperObservable<Observer> getObservable(Class<Observer> observableName){
SuperObservable<Observer> superObservable = mObservables.get(observableName);
if(superObservable==null){
throw new IllegalStateException("未添加"+observableName.getSimpleName()+"類型的被觀察者!");
}
return superObservable;
}
/**
* 移除被觀察者
* @param observableName
* @return
*/
public SuperObservable removeObservable(Class observableName){
return mObservables.remove(observableName);
}
}
順便說一下我對觀察者模式的理解。觀察者模式本質(zhì)就是接口回調(diào),不過平時我們常用的是回調(diào)給一個對象,而觀察者一次性回調(diào)給多個對象。 可以解決 Activity與Fragment各種回調(diào),例如app登錄之后要把登錄狀態(tài)回調(diào)給諸多Activity與Fragment。

1488457866952.jpg