Android 观察者模式,这么讲你还不理解吗

观察者模式:顾名思义,就是众多观察者(observers)对被观察者(observable)的状态、行为等进行监听,
             当被观察者(observable)的状态、行为等发生改变后,向观察者(observers)发出通知,告知观察者(observers),
            观察者可以对这些通知进行处理或者不处理。

举个例子:
比如在上课的时候,老师可以看成一个被观察者(observable),所有学生可以看成观察者(observers)
老师(observable)喊上课之后,所有同学(observers)的注意力都集中在老师身上,这时候相当于给被观察者(observable)添加了许多观察者(observers);
被观察者(老师)(observable)的一言一行都会通过光或者声音反馈给到同学们(observers),当然同学们(observers)对
老师(observable)的言行可能有所反应或者不做任何响应。比如在看到老师(observable)走过来的时候,没认真听讲的同学(observers)赶紧坐好,集中注意(响应),认真听讲的同学(observers)则可以不做反应。
当然在收到老师(observable)【放学】的通知后,同学们都背起书包回家,即都响应了。

从上面例子可以看出,观察者(observers)一定要有接收被观察者(observable)通知的能力;
被观察者(observable)一定要有增加观察者(observers)的和通知观察者(observers)的能力;
那么我们可以将这些能力抽象出来,让具体的实现必须实现这些能力,然后添加观察者(observers)的时候
只关心他有没有接收通知的能力(即是否是抽象观察者类observers的实现类)。至此,以及结合高内聚低耦合的思想,我们可以看到,
观察者模式有4个必要元素:
1.观察者抽象类
2.观察者具体实现类
3.被观察者抽象类
4.被观察者具体实现类

下面来具体实现以下:

观察者抽象类:

public abstract class Observerabstract {

    /**
     * 必须有接收通知的能力
     * @param msg
     */
    abstract void update(String msg);
}

观察者具体实现类:

public class MyObserver extends Observerabstract {
    //传入名称,区分不同的观察者
    private String name;

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

    @Override
    public void update(String msg) {
        System.out.print(String.format("%s 收到了新消息: %s \n",name,msg));
//        System.out.print(name+ "收到特急书信: "+msg);
//        Log.i("魔教求助信",name+ "收到特急书信: "+msg);
    }
}

被观察者抽象类:

public abstract class Observableabstract {
    /**
     * 增加观察者
     * @param observer 观察者实例对象
     */
    abstract void add(Observerabstract observer);

    /**
     * 移除观察者
     * @param observer 需要移除的观察者对象
     */
    abstract void move(Observerabstract observer);

    /**
     * 数据变更是通知观察者
     */
    abstract void notifyObserver();
}

被观察者具体实现类:

public class MyObservable extends Observableabstract {
    //保存有多少个观察者要对此被观察者进行观察
    private List observerList;

    private String message;

    public MyObservable() {
        observerList = new ArrayList<>();
    }

    
    @Override
    public void add(Observerabstract observer) {
        observerList.add(observer);
    }

    @Override
    public void move(Observerabstract observer) {
        observerList.remove(observer);
    }

    @Override
    public void notifyObserver() {
        for (Observerabstract observer:observerList){
            observer.update(message);
        }
        


    }

    public void setMessage(String message) {
        this.message = message;
        notifyObserver();
    }
}

再来看看咱们recycleview的adapter中的源码

观察者抽象类:

  /**
     * Observer base class for watching changes to an {@link Adapter}.
     * See {@link Adapter#registerAdapterDataObserver(AdapterDataObserver)}.
     */
    public abstract static class AdapterDataObserver {
        public void onChanged() {
            // Do nothing
        }

        public void onItemRangeChanged(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
            // fallback to onItemRangeChanged(positionStart, itemCount) if app
            // does not override this method.
            onItemRangeChanged(positionStart, itemCount);
        }

        public void onItemRangeInserted(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeRemoved(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            // do nothing
        }
    }

观察者具体实现类:

  private class RecyclerViewDataObserver extends AdapterDataObserver {
        RecyclerViewDataObserver() {
        }

        @Override
        public void onChanged() {
            assertNotInLayoutOrScroll(null);
            mState.mStructureChanged = true;

            processDataSetCompletelyChanged(true);
            if (!mAdapterHelper.hasPendingUpdates()) {
                requestLayout();
            }
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            assertNotInLayoutOrScroll(null);
            if (mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)) {
                triggerUpdateProcessor();
            }
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            assertNotInLayoutOrScroll(null);
            if (mAdapterHelper.onItemRangeInserted(positionStart, itemCount)) {
                triggerUpdateProcessor();
            }
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            assertNotInLayoutOrScroll(null);
            if (mAdapterHelper.onItemRangeRemoved(positionStart, itemCount)) {
                triggerUpdateProcessor();
            }
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            assertNotInLayoutOrScroll(null);
            if (mAdapterHelper.onItemRangeMoved(fromPosition, toPosition, itemCount)) {
                triggerUpdateProcessor();
            }
        }

        void triggerUpdateProcessor() {
            if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {
                ViewCompat.postOnAnimation(RecyclerView.this, mUpdateChildViewsRunnable);
            } else {
                mAdapterUpdateDuringMeasure = true;
                requestLayout();
            }
        }
    }

被观察者抽象类:

/**
 * Provides methods for registering or unregistering arbitrary observers in an {@link ArrayList}.
 *
 * This abstract class is intended to be subclassed and specialized to maintain
 * a registry of observers of specific types and dispatch notifications to them.
 *
 * @param T The observer type.
 */
public abstract class Observable {
    /**
     * The list of observers.  An observer can be in the list at most
     * once and will never be null.
     */
    protected final ArrayList mObservers = new ArrayList();

    /**
     * Adds an observer to the list. The observer cannot be null and it must not already
     * be registered.
     * @param observer the observer to register
     * @throws IllegalArgumentException the observer is null
     * @throws IllegalStateException the observer is already registered
     */
    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);
        }
    }

    /**
     * Removes a previously registered observer. The observer must not be null and it
     * must already have been registered.
     * @param observer the observer to unregister
     * @throws IllegalArgumentException the observer is null
     * @throws IllegalStateException the observer is not yet registered
     */
    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);
        }
    }

    /**
     * Remove all registered observers.
     */
    public void unregisterAll() {
        synchronized(mObservers) {
            mObservers.clear();
        }
    }
}

被观察者具体实现类:

static class AdapterDataObservable extends Observable {
        public boolean hasObservers() {
            return !mObservers.isEmpty();
        }

        public void notifyChanged() {
            // since onChanged() is implemented by the app, it could do anything, including
            // removing itself from {@link mObservers} - and that could cause problems if
            // an iterator is used on the ArrayList {@link mObservers}.
            // to avoid such problems, just march thru the list in the reverse order.
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onChanged();
            }
        }

        public void notifyItemRangeChanged(int positionStart, int itemCount) {
            notifyItemRangeChanged(positionStart, itemCount, null);
        }

        public void notifyItemRangeChanged(int positionStart, int itemCount,
                @Nullable Object payload) {
            // since onItemRangeChanged() is implemented by the app, it could do anything, including
            // removing itself from {@link mObservers} - and that could cause problems if
            // an iterator is used on the ArrayList {@link mObservers}.
            // to avoid such problems, just march thru the list in the reverse order.
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload);
            }
        }

        public void notifyItemRangeInserted(int positionStart, int itemCount) {
            // since onItemRangeInserted() is implemented by the app, it could do anything,
            // including removing itself from {@link mObservers} - and that could cause problems if
            // an iterator is used on the ArrayList {@link mObservers}.
            // to avoid such problems, just march thru the list in the reverse order.
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onItemRangeInserted(positionStart, itemCount);
            }
        }

        public void notifyItemRangeRemoved(int positionStart, int itemCount) {
            // since onItemRangeRemoved() is implemented by the app, it could do anything, including
            // removing itself from {@link mObservers} - and that could cause problems if
            // an iterator is used on the ArrayList {@link mObservers}.
            // to avoid such problems, just march thru the list in the reverse order.
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onItemRangeRemoved(positionStart, itemCount);
            }
        }

        public void notifyItemMoved(int fromPosition, int toPosition) {
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onItemRangeMoved(fromPosition, toPosition, 1);
            }
        }
    }

很像吧,还有很多地方都用的观察者模式呢,比如jetpack里面! 

你可能感兴趣的:(Android)