觀察者模式--Java設計模式

來源:互聯網
上載者:User

標籤:設計模式   觀察者模式   

觀察者模式定義:定義了對象之間的一對多的依賴,這樣一來,當一個對象發生改變狀態的時候,它的所有依賴者都會收到通知並自動更新。參考如:

觀察者設計模式也叫發布-訂閱模式。
也可以稱作:出版者+訂閱者 = 觀察者模式
在Android中觀察者模式的執行個體有:廣播機制,ContentObserver的註冊方式,一個是同步的觀察者模式,一個是非同步觀察者模式。

當兩個對象之間松耦合,它們依然可以互動,但是不清楚彼此的細節,觀察者提供了一種對象的設計,可以降低之間的耦合,避免對象的雙向依賴。
舉例:在Android中很多的Listener是觀察者模式,比如點擊事件的OnClickListener,就是為了避免對象的雙向依賴。

—-先來看看Java源碼中的觀察者模式:Observer觀察者介面:
package com.daming.java.observer;public interface Observer {    void update(Observable observable, Object arg);}
對象Observable 類的實現
package com.daming.java.observer;import java.util.Vector;public class Observable {    private boolean changed = false;    private Vector obs;    public Observable() {        obs = new Vector();    }    public synchronized void addObserver(Observer o) {        if (o == null)            throw new NullPointerException();        if (!obs.contains(o)) {            obs.addElement(o);        }    }    public synchronized void deleteObserver(Observer o) {        obs.removeElement(o);    }    public void notifyObservers() {        notifyObservers(null);    }    public void notifyObservers(Object arg) {        Object[] arrLocal;        synchronized (this) {            if (!changed)                return;            arrLocal = obs.toArray();            clearChanged();        }        for (int i = arrLocal.length - 1; i >= 0; i--)            ((Observer) arrLocal[i]).update(this, arg);    }    public synchronized void deleteObservers() {        obs.removeAllElements();    }    protected synchronized void setChanged() {        changed = true;    }    protected synchronized void clearChanged() {        changed = false;    }    public synchronized boolean hasChanged() {        return changed;    }    /**     * Returns the number of observers of this <tt>Observable</tt> object.     *      * @return the number of observers of this object.     */    public synchronized int countObservers() {        return obs.size();    }}
MyObserver 觀察者對象的實現
package com.daming.java.observer;public class MyObserver implements Observer{    @Override    public void update(Observable observable, Object arg) {        System.out.println("observable :" + observable + "arg :" + arg);    }}
MyObserver2 觀察者對象的實現
package com.daming.java.observer;public class MyObserver2 implements Observer{    @Override    public void update(Observable observable, Object arg) {        System.out.println("observable2 :" + observable + "arg2 :" + arg);    }}
TestObserver類的實現
package com.daming.java.observer;public class TestObserver {    /**     * @param args     */    public static void main(String[] args) {        Observable observable = new Observable();        MyObserver myObserver = new MyObserver();        MyObserver2 myObserver2 = new MyObserver2();        observable.addObserver(myObserver);        observable.addObserver(myObserver2);        observable.setChanged();        observable.notifyObservers(14);        observable.setChanged();        observable.notifyObservers("I am daming");    }}
Log輸入結果:
observable2 :com.daming.java.observer.Observable@14318bbarg2 :14observable :com.daming.java.observer.Observable@14318bbarg :14observable2 :com.daming.java.observer.Observable@14318bbarg2 :I am damingobservable :com.daming.java.observer.Observable@14318bbarg :I am daming

Java源碼中上述代碼中用的是推模式,當然源碼中也有拉模式,即主動查詢的模式。拉模式就像廣播一樣,通過onReceive()方法拉起來一些動作的,還有像ContentObserver可以通過拉模式,當資料庫發生改變的時候,通過onChange()方法來調用一些操作。

—-接著我們來看看Android中非同步觀察者模式。

ContentObserver就是非同步觀察者模式,非同步觀察者有什麼好處呢?不阻塞觀察者的回調。在同步通知中會有阻塞問題,各個Observer的回應程式法是串列的,如果有一個observer耗時的話就會阻塞其他observer接收者了,這樣就有可能就會引起bug來,所以在設計的時候多考慮一些,是否考慮用非同步觀察者模式,讓並發處理快一些;我們通過一個簡單的demo來學習下非同步觀察者模式:

先來看看Observer,這個Android中是抽象的類
package cn.daming.observer.design;import android.os.Handler;import android.util.Log;public abstract class Observer {    private Handler mHandler;    public Observer(Handler handler) {        mHandler = handler;    }    public void onChange() {    }    public final void dispatchChange() {        Log.v("daming", "Observer dispatchChange is mHandler== null :" + (mHandler == null));        if (mHandler == null) {            onChange();        } else {            mHandler.post(new NotificationRunnable());        }    }    private final class NotificationRunnable implements Runnable {        @Override        public void run() {            Log.v("daming", "NotificationRunnable dispatchChange is run ... ");            Observer.this.onChange();        }    }}
接著來看看ObserverService這個類的實現:
package cn.daming.observer.design;import java.util.ArrayList;import java.util.List;import android.util.Log;public class ObserverService {    private int mState;    private List<Observer> mObservers = new ArrayList<Observer>();    public final void registerObserver(Observer observer) {        if (!mObservers.contains(observer)) {            mObservers.add(observer);        }    }    public final void unregisterObserver(Observer observer) {        Log.v("daming", "ObserverService unregisterObserver :");        mObservers.remove(observer);    }    public void notifyChange() {        for (Observer observer : mObservers) {            observer.dispatchChange();        }    }    public int getState() {        return mState;    }    public void setState(int state) {        mState = state;        notifyChange();    }}
最後我們來寫測試類別FirstActivity :
package cn.daming.observer.design;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import com.daming.designtraning.R;public class FirstActivity extends Activity {    private ObserverService mObserverService;    private Button mButton;    private int mState = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mButton = (Button) findViewById(R.id.button);        mObserverService = new ObserverService();        mObserverService.registerObserver(mFirstObserver);        mObserverService.setState(++mState);        mButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                mObserverService.setState(++mState);            }        });    }    @Override    protected void onDestroy() {        super.onDestroy();        mObserverService.unregisterObserver(mFirstObserver);    }    @Override    protected void onResume() {        super.onResume();    }    @Override    protected void onStop() {        super.onStop();    }    private Observer mFirstObserver = new Observer(new Handler()) {        @Override        public void onChange() {            int state = mObserverService.getState();            Log.v("daming", "FirstObserver onChange is run state :" + state);        }    };}

總結:通過Handler來實現非同步觀察者模式,即構造Observer對象的時候傳一個Handler的對象,這樣在回調的時候,就用handler來發送非同步訊息在主線程上來執行相應的操作。

觀察者模式--Java設計模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.