Android 觀察者模式
Android 設計模式系列文章Android 23種設計模式
前言
觀察者模式是我們使用率比較高的一種模式了。這類文章網上也不少,通過本文我會讓你徹底理解並記住什麼事觀察者模式。觀察者模式使用率之所以比較高,是因為它在Android中能達到一個十分明顯的解耦效果。讓觀察者和被觀察者邏輯分開。使得UI層和業務邏輯清晰。更加利於我們拓展程式碼。
觀察者模式定義
定義一個被觀察者和多個觀察者,每當被觀察者變化,所有觀察者都會得到通知。
理解重點
觀察者模式核心就一個點,記住這個點你就能理解並記憶。要點:用一個list把觀察者儲存起來,並提供add和remove觀察者,在被觀察者變化的時候就遍歷並呼叫list裡觀察者的方法。核心就是一個list遍歷
下面我將用兩個例子來具體說明觀察者模式。例一是JDK自帶的介面,例二是自己寫觀察者模式
例子一
先來一個訂閱釋出的例子。我們定義Android釋出新的版本。Android為被觀察者,當新版本釋出的時候,我們通知所有觀察者,新版本已釋出。
1、定義觀察者
public class PersonObserver implements Observer { static final String TAG = PersonObserver.class.getSimpleName(); String name; public PersonObserver (String name) { this.name = name; } @Override public void update(Observable observable, Object o) { Log.d(TAG,name + " 接收到通知啦 "+ o); } }
觀察者就實現一個介面update方法,當被觀察者傳送訊息的時候,我們就在update裡接收
2、定義被觀察者
public class AndroidObervable extends Observable { static final String TAG = AndroidObervable.class.getSimpleName(); public void postNewVersion(String version) { setChanged(); // 標示內容發生改變 notifyObservers(version);// 通知所有觀察者 } }
被觀察者繼承自Observable,Observable裡已經定義好了list,add,delete等方法,很好理解。
3、最後我們來看下怎麼用的
PersonObserver xiaoMing = new PersonObserver("xiaoMing"); PersonObserver xiaoDong = new PersonObserver("xiaoDong"); PersonObserver xiaoHong = new PersonObserver("xiaoHong"); // 新增到集合裡。 AndroidObervable android = new AndroidObervable(); android.addObserver(xiaoMing); android.addObserver(xiaoDong); android.addObserver(xiaoHong); // 通知 android.postNewVersion("android O updated!"); android.postNewVersion("android P updated!");
11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoMing 接收到通知啦 android O updated! 11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoDong 接收到通知啦 android O updated! 11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoHong 接收到通知啦 android O updated! 11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoMing 接收到通知啦 android P updated! 11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoDong 接收到通知啦 android P updated! 11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoHong 接收到通知啦 android P updated!
看輸出都通知到了。觀察者模式採用JDK原生的方式實現起來很簡單。JDK都給我們封裝好了。只管新增就好。這個例子適合我們先對觀察者模式有一個大概理解,知道這就是觀察者模式。
例二
接下來我們自己來實現觀察者模式。我們以觀察天氣變化為例。
1、定義觀察者
public abstract class WeatherOberver { public void typhoon() { } public abstract void sun(); public abstract void rain(); }
這裡和例一的差別是,我們用的抽象類,沒用介面,他們思想都相似。這裡我是為了區分事件,我們也可以用介面寫,然後把各種天氣用一個變量表示,這裡就不詳述了。
2、定義被觀察者
public class WeatherObervable extends WeatherOberver{ ArrayList<WeatherOberver> list = new ArrayList<>(); public void add(WeatherOberver observerListener) { list.add(observerListener); } public void remove(WeatherOberver observerListener) { if (list.contains(observerListener)){ list.remove(observerListener); } } @Override public void typhoon() { for (WeatherOberver observerListener : list) { observerListener.typhoon(); } } @Override public void sun() { for (WeatherOberver observerListener : list) { observerListener.sun(); } } @Override public void rain() { for (WeatherOberver observerListener : list) { observerListener.rain(); } } }
被觀察者的實現也是簡單粗暴。這裡就體現了我們文章開始的時候說的觀察者模式的核心了。一個list提供add,remove方法,把觀察者放到集合裡。需要通知的時候遍歷通知即可。這下就好理解了吧。
3、最後看看呼叫。
private WeatherOberver xiaoDong = new WeatherOberver() { @Override public void typhoon() { Log.d("xiaoDong","吹臺風,要放假了。哈哈!"); } @Override public void sun() { } @Override public void rain() { Log.d("xiaoDong","下雨了,帶傘"); } }; private WeatherOberver xiaoMing = new WeatherOberver() { @Override public void sun() { } @Override public void rain() { Log.d("xiaoMing","下雨了,帶傘"); } }; WeatherObervable weatherObervable = new WeatherObervable(); weatherObervable.add(xiaoMing); weatherObervable.add(xiaoDong); weatherObervable.rain(); weatherObervable.typhoon();
11-20 11:16:21.284 15580-15580/com.yink.designpattern.designpattern D/xiaoMing: 下雨了,帶傘 11-20 11:16:21.284 15580-15580/com.yink.designpattern.designpattern D/xiaoDong: 下雨了,帶傘 11-20 11:16:21.284 15580-15580/com.yink.designpattern.designpattern D/xiaoDong: 吹臺風,要放假了。哈哈!
因為觀察者我用的抽象類,除了天晴和下雨是必須繼承的方法,刮颱風可繼承可不繼承。所以我們可以更方便的觀察我們需要觀察的物件。小東在廣東,吹臺風他們公司就放假。所以他只關心哪天吹臺風。小明比較講究健康,關注下雨,下雨就帶傘。
觀察者模式小結
觀察者模式就是將觀察者和被觀察者徹底隔離,實現解耦,只依賴於我們定義的抽象。觀察者模式運用十分廣泛,比如我們的ListView運用了觀察者模式和Adapter是的Listview的可擴充套件性,靈活性非常強。還有比較出名的開源庫EventBus也是用了觀察者模式的思想實現解耦。
總結
優點:1、觀察者和被觀察者解耦2、增強靈活性,解耦
缺點:由於java程式碼的順序執行,要考慮被察者的執行效率,多個觀察者需要及時響應就得考慮非同步的問題了。
觀察模式核心:一個list合集,提供add,remove方法,遍歷觀察者,就是一個list的遍歷。