學(xué)習(xí)《Android 源碼設(shè)計(jì)模式解析與實(shí)踐》系列筆記
介紹
觀察者模式是使用率非常高的模式,最常用在 GUI 系統(tǒng)、訂閱-發(fā)布系統(tǒng)铁瞒。觀察者模式的重要作用是使被觀察者和觀察者間的解耦势似,使它們間的依賴性變小歌豺。
觀察者模式屬于行為型模式推穷。
定義
觀察者設(shè)計(jì)模式定義了對(duì)象間的一種一對(duì)多的組合關(guān)系,以便一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí)类咧,所有依賴于它的對(duì)象都得到通知并自動(dòng)刷新缨恒。
使用場(chǎng)景
- 關(guān)聯(lián)場(chǎng)景,需要注意的是轮听,關(guān)聯(lián)行為是可拆分的,而不是"組合"關(guān)系岭佳。
- 事件多級(jí)觸發(fā)場(chǎng)景血巍。
- 跨系統(tǒng)的消息交換場(chǎng)景,如消息隊(duì)列珊随、事件總線的處理機(jī)制述寡。
結(jié)構(gòu)
- Subject : 抽象被觀察者柿隙,提供接口添加和刪除觀察者。
- ConcreteSubject : 具體被觀察者鲫凶,需要處理消息的通知禀崖。
- Observer :抽象觀察者,定義了更新的接口螟炫。
- ConcreteObserver : 具體的觀察者波附,需要實(shí)現(xiàn)更新接口接收處理消息。
實(shí)現(xiàn)
在開(kāi)發(fā)中昼钻,經(jīng)常需要監(jiān)聽(tīng)網(wǎng)絡(luò)的變化掸屡。比如視頻播放頁(yè)面,在從 wifi 切換到 流量的時(shí)候然评,需要暫停播放提醒用戶仅财。有些頁(yè)面從無(wú)網(wǎng)到有網(wǎng)時(shí),需要自動(dòng)刷新頁(yè)面碗淌。這里的網(wǎng)絡(luò)狀態(tài)就是被觀察者盏求,而需要這些狀態(tài)的則為觀察者。
定義 Observer 抽象接口
public interface NetworkObserver {
void onConnected(boolean connected);
}
NetworkUtil 被觀察者 (這里只提取了關(guān)鍵的函數(shù))
public class NetworkUtil {
private static BroadcastReceiver sReceiver;
private static List<NetworkObserver> sObservers = new ArrayList<>();
/**
* 注冊(cè)網(wǎng)絡(luò)連接監(jiān)聽(tīng)亿眠。
*/
public static synchronized void registerBroadcast(Context context) {
if (sReceiver == null) {
sReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 網(wǎng)絡(luò)變化碎罚,通知觀察者
for (NetworkObserver observer : sObservers) {
observer.onConnected(isNetworkAvailable(context));
}
}
};
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(sReceiver, filter);
}
}
/**
* 取消網(wǎng)絡(luò)連接監(jiān)聽(tīng)。
*/
public static synchronized void unRegisterReceiver(Context context) {
if (sReceiver != null) {
context.unregisterReceiver(sReceiver);
sReceiver = null;
}
}
/**
* 添加網(wǎng)絡(luò)監(jiān)聽(tīng)
*/
public static void addObserver(NetworkObserver observer) {
if (observer != null && !sObservers.contains(observer)) {
sObservers.add(observer);
}
}
/**
* 取消網(wǎng)絡(luò)監(jiān)聽(tīng)
*/
public static void removeObserver(NetworkObserver observer) {
if (observer != null) {
sObservers.remove(observer);
}
}
}
具體觀察者的實(shí)現(xiàn)
這個(gè)是靜態(tài)的內(nèi)部類缕探,只提取了這個(gè)類出來(lái)
private static class MyNetworkObserver implements NetworkUtil.NetworkObserver {
@Override
public void onConnected(boolean connected) {
//接收到通知后魂莫,具體的業(yè)務(wù)需要
...
}
}
// 在合適的地方添加和移除監(jiān)聽(tīng)
// 添加監(jiān)聽(tīng)
mNetworkObserver = new MyNetworkObserver(this);
NetworkUtil.addObserver(mNetworkObserver);
//移除監(jiān)聽(tīng)
NetworkUtil.removeObserver(mNetworkObserver);
Android 源碼中的應(yīng)用
監(jiān)聽(tīng)者模式在 Android
中的應(yīng)用場(chǎng)景還是挺多的,比如各種點(diǎn)擊事件爹耗、觸摸事件的監(jiān)聽(tīng) OnClickListener
還有 ContentObserver
, ListView
的 Adapter
中的 AdapterDataSetObserver
等耙考。
總結(jié)
優(yōu)點(diǎn):
- 觀察者和被觀察者間的解耦。
缺點(diǎn):
- 如果一個(gè)被觀察者對(duì)象有很多的直接和間接的觀察者的話潭兽,將所有的觀察者都通知到會(huì)花費(fèi)很多時(shí)間倦始。
相關(guān)文章:
設(shè)計(jì)模式整理(1) 代理模式
設(shè)計(jì)模式整理(2) 單例模式
設(shè)計(jì)模式整理(3) Builder 模式
設(shè)計(jì)模式整理(4) 原型模式
設(shè)計(jì)模式整理(5) 工廠模式
設(shè)計(jì)模式整理(6) 策略模式
設(shè)計(jì)模式整理(7) 狀態(tài)模式
設(shè)計(jì)模式整理(8) 責(zé)任鏈模式
設(shè)計(jì)模式整理(9) 觀察者模式
設(shè)計(jì)模式整理(10) 適配器模式
設(shè)計(jì)模式整理(11) 裝飾模式
設(shè)計(jì)模式整理(12) 中介者模式