Android 設計模式情景分析——觀察者模式

來源:互聯網
上載者:User

標籤:構建   --   優缺點   imp   關係   並且   非同步作業   軟體測試   擴充性   

觀察者模式是一種使用頻率非常高的模式,有時也被稱作發布/訂閱模式,屬於行為型模式,它最常用的是 GUI 系統、訂閱——發布系統,它一個重要作用就是解耦,使得它們之間的依賴性更小。觀察者模式定義了對象間一種一對多的依賴關係,使得每當一個對象改變狀態時,則所有依賴於它的對象都會得到通知並被自動更新。

1.觀察者模式的使用情景

關聯線為情境;事件多級觸發情境;跨系統的訊息交換情境(如訊息佇列、事件匯流排的處理機制)。

2.程式中使用觀察者模式的優缺點
- 觀察者模式
優點 觀察者和被觀察者之間是耦合抽象,應對業務變化;增強了系統靈活性、可擴充性。
缺點 開發調試變的比較複雜,Java中訊息的通知是順序執行,一個訊息的卡頓會影響整體的執行效率,所以使用觀察者模式還需要結合非同步作業的方式。
3.觀察者模式的UML類圖

Subject:抽象主題,被觀察(Observable)的角色;ConcreteSubject:具體主題;Observer:抽象觀察者;ConcreteObserver:具體的觀察者。

4.觀察者模式的實現

觀察者 Observer 和被觀察者 Observable 是 JDK 中的內建類型。

1.建立觀察者:

public class MyObserver implements Observer {    private String name;    public MyObserver(String name) {        this.name = name;    }    @Override    public void update(Observable o, Object arg) {        System.out.println(name + ", update:" + arg);    }}

3.編寫測試方法:

@Testpublic void test() throws Exception {    // 被觀察者    MyObservable observable = new MyObservable();    // 觀察者    MyObserver observer1 = new MyObserver("test1");    MyObserver observer2 = new MyObserver("test2");    MyObserver observer3 = new MyObserver("test3");    MyObserver observer4 = new MyObserver("test4");    // 將觀察者註冊到被觀察者對象的觀察者列表中    observable.addObserver(observer1);    observable.addObserver(observer2);    observable.addObserver(observer3);    observable.addObserver(observer4);    // 發布訊息    observable.postNewPublication("new");}

輸出結果:

test4, update:newtest3, update:newtest2, update:newtest1, update:new

可以看到所有訂閱了被觀察者的觀察者都接收到了更新訊息,一對多的訂閱——發布系統就完成了。

5.Android系統原始碼中的應用情景1.notifyDataSetChanged() 方法

我們在使用 ListView 添加資料後,都會調用 Adapter 的 notifyDataSetChanged() 方法來動態更新資料。

notifyDataSetChanged() 方法被定義在 BaseAdapter 中,BaseAdapter 就是一個觀察者模式:

public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {    // 資料集觀察者    private final DataSetObservable mDataSetObservable = new DataSetObservable();    public void registerDataSetObserver(DataSetObserver observer) {        mDataSetObservable.registerObserver(observer);    }    public void unregisterDataSetObserver(DataSetObserver observer) {        mDataSetObservable.unregisterObserver(observer);    }    // 當資料集變化時,通知所有觀察者    public void notifyDataSetChanged() {        mDataSetObservable.notifyChanged();    }    // 代碼省略}


我們跟進查看 mDataSetObservable.notifyChanged() 方法:
public class DataSetObservable extends Observable<DataSetObserver> {    // 調用每個觀察者的 onChanged() 方法來通知它們被觀察者發生了變化    public void notifyChanged() {        synchronized(mObservers) {            // 調用所有觀察者的 onChanged() 方法            for (int i = mObservers.size() - 1; i >= 0; i--) {                mObservers.get(i).onChanged();            }        }    }    // 代碼省略}

這段代碼就是在 mDataSetObservable.notifyChanged() 中遍曆所有觀察者,並且調用它們的 onChanged() 方法,從而告知觀察者發生了變化。

那麼這些觀察者是哪裡來的呢?其實是 ListView 通過 setAdapter() 方法設定 Adapter 產生的,我們來看看相關代碼:

public class ListView extends AbsListView {    // 代碼省略    @Override    public void setAdapter(ListAdapter adapter) {        // 如果已經有了一個 Adapter,那麼先登出該 Adapter 對應的觀察者        if (mAdapter != null && mDataSetObserver != null) {            mAdapter.unregisterDataSetObserver(mDataSetObserver);        }        // 代碼省略        super.setAdapter(adapter);        if (mAdapter != null) {            mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();            mOldItemCount = mItemCount;            // 擷取資料的數量            mItemCount = mAdapter.getCount();            checkFocus();            // 這裡注意:建立一個一個資料集觀察者            mDataSetObserver = new AdapterDataSetObserver();            // 將這個觀察者註冊到 Adapter 中,實際上是註冊到 DataSetObservable 中            mAdapter.registerDataSetObserver(mDataSetObserver);            // 代碼省略        } else {            // 代碼省略        }        requestLayout();    }    // 代碼省略}

我們可以看到,在設定 Adapter 時會構建一個 AdapterDataSetObserver,也就是觀察者,最後,將這個觀察者註冊到 Adapter 中。

到這裡,我們就知道了,當 ListView 的資料發生變化時,調用 Adapter 的 notifyDataSetChanged() 方法,這個方法又調用 DataSetObservable 的 notifyChanged() 方法,這個方法又調用所有觀察者(AdapterDataSetObserver)的 onChanged() 方法,在 onChanged() 方法中又會調用 ListView 重新布局的方法使得 ListView 重新整理介面,這就是一個觀察者模式。

Android 設計模式情景分析——觀察者模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.