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