Android設計模式系列--觀察者模式
觀察者模式,是一種非常常見的設計模式,在很多系統(tǒng)中隨處可見,尤其是涉及到數(shù)據(jù)狀態(tài)發(fā)生變化需要通知的情況下。
本文以AbstractCursor為例子,展開分析。
觀察者模式,Observer Pattern,是一個很實用的模式,本人曾經(jīng)接觸到的各種平臺以及曾經(jīng)參與項目中打印模板解釋器中都用到了此模式。
1.意圖
定義對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。
熱門詞匯:依賴 發(fā)布-訂閱 事件 通知 更新 監(jiān)聽
2.結(jié)構(gòu)
這是一個最簡單的觀察者模式,目標對象能夠添加和刪除觀察者,當自己某種狀態(tài)或者行為發(fā)生改變時,可通過notify通知注冊的觀察者進行更新操作。
分析AbstractCursor的具體情況,我們發(fā)現(xiàn)實際工作有時需要對觀察者進行統(tǒng)一管理,甚至觀察者類型有很多種而又可以分成幾個系列,這個時候是要復雜的多,通過合理的分層這個問題很好解決。下面根據(jù)具體情況,我們畫出android中abstractCurosr中用到的觀察者模式結(jié)構(gòu)圖:
觀察者分成了兩個系列。
3.代碼
列舉其中相關核心代碼如下:
- public abstract class AbstractCursor {
- //定義管理器
- DataSetObservable mDataSetObservable = new DataSetObservable();
- ContentObservable mContentObservable = new ContentObservable();
- //注冊和卸載兩類觀察者
- public void registerContentObserver(ContentObserver observer) {
- mContentObservable.registerObserver(observer);
- }
- public void unregisterContentObserver(ContentObserver observer) {
- // cursor will unregister all observers when it close
- if (!mClosed) {
- mContentObservable.unregisterObserver(observer);
- }
- }
- public void registerDataSetObserver(DataSetObserver observer) {
- mDataSetObservable.registerObserver(observer);
- }
- public void unregisterDataSetObserver(DataSetObserver observer) {
- mDataSetObservable.unregisterObserver(observer);
- }
- //2類通知方法
- protected void onChange(boolean selfChange) {
- synchronized (mSelfObserverLock) {
- mContentObservable.dispatchChange(selfChange);
- if (mNotifyUri != null && selfChange) {
- mContentResolver.notifyChange(mNotifyUri, mSelfObserver);
- }
- }
- }
- protected void notifyDataSetChange() {
- mDataSetObservable.notifyChanged();
- }
- }
再看看Observable<T>類和DataSetObservable類:
- 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();
- }
- }
- }
和
- public class DataSetObservable extends Observable<DataSetObserver> {
- /**
- * 數(shù)據(jù)發(fā)生變化時,通知所有的觀察者
- */
- public void notifyChanged() {
- synchronized(mObservers) {
- for (DataSetObserver observer : mObservers) {
- observer.onChanged();
- }
- }
- }
- //... ... (其他方法)
- }
觀察者DataSetObserver類是一個抽象類:
- public abstract class DataSetObserver {
- public void onChanged() {
- // Do nothing
- }
- }
所以我們具體看它的子類:
- public class AlphabetIndexer extends DataSetObserver{
- /*
- * @hide 被android系統(tǒng)隱藏起來了
- */
- @Override
- public void onChanged() {
- //觀察到數(shù)據(jù)變化,觀察者做自己該做的事情
- super.onChanged();
- mAlphaMap.clear();
- }
- }
ContentObserver也是類似。
4.效果
(1).行為型模式
(2).目標和觀察者間的抽象耦合(經(jīng)典實現(xiàn))。
(3).支持廣播通信(相信這點android開發(fā)者看到后應該有啟發(fā)吧)。
(4).注意意外的更新,這也是觀察者更新進行管理的原因之一。