上一篇 OkHttp設計模式剖析(四)享元模式
下一篇 OkHttp設計模式剖析(六)外觀模式
OKHTTP:
由大名鼎鼎的Square公司開發的網絡通信庫。
設計模式:
軟件開發中問題的解決套路。
觀察者模式簡介
定義:定義對象間一種一對的依賴關系,使得每當一個對象改變狀態,則所有依賴于它的對象都會得到廣播通知并被自動更新。
其實觀察者模式(Observer Pattern)叫做發布-訂閱模式更合適。發布者一旦更新消息,所有訂閱者都能收到。觀察者模式也很適用于UI事件觸發和偵聽,消息交換等場景
Observer和Observable是JDK中的內置類型,若一個對象繼承了Observer類,那么這段代碼大概率用了觀察者模式。
OkHttp中WebSocket監聽器中的觀察者模式
OkHttp中WebSocket的觀察者模式并不典型,它并不是一對多的觀察者模式。而是一個WebSocketListener監聽一個Socket的觀察者模式,這種觀察者是基于回調函數處理的。
在一個連接WebSocket上的消息監聽器Listener,所有回調都將在單個線程上調用,監聽器遵循生命周期規則。源碼如下:
public interface WebSocketListener {
// WebSocket 打開 則調用onOpen
void onOpen(WebSocket webSocket, Response response);
// 接收到Server端發來的Message 則調用onMessage
void onMessage(ResponseBody message) throws IOException;
// 接收到Server端發來的Pong 則調用onPong
void onPong(ByteString payload);
// WebSocket 關閉 則調用onClose
void onClose(int code, String reason);
// WebSocket 錯誤 則調用onFailure
void onFailure(Throwable t, Response response);
}
定義WebSocketCall接口,源碼如下:
public interface WebSocketCall extends Cloneable {
//返回啟動此調用的原始請求。
Request request();
// 監聽器入隊,安排在將來某個時間點執行請求。
void enqueue(WebSocketListener listener);
// 取消請求
void cancel();
// 若此WebSocketCall入隊,返回true
boolean isExecuted();
boolean isCanceled();
WebSocketCall clone();
interface Factory {
WebSocketCall newWebSocketCall(Request request);
}
}
此時監聽器已經成為訂閱者。WebSocket接口的實現類RealWebSocket若處于開啟狀態,持續監聽Socket接收消息。那么訂閱之后會有什么響應呢?我們跳轉到實現WebSocketCall接口的RealWebSocketCall類,重點閱讀enqueue()函數:
@Override public void enqueue(final WebSocketListener listener) {
Callback responseCallback = new Callback() { // 監聽后必然得回調
@Override public void onResponse(Call call, Response response) {
StreamWebSocket webSocket;
try {
webSocket = create(response, listener);
} catch (IOException e) {
listener.onFailure(e, response);
return;
}
webSocket.loopReader(); // 開始輪訓讀取消息
}
@Override public void onFailure(Call call, IOException e) {
listener.onFailure(e, null);
}
};
call.enqueue(responseCallback);
}
回調函數是一種特殊的觀察者模式,是一種一對一的觀察者模式。
基于觀察者模式構建的其他代碼
1、Android的BroadcastRecevier廣播機制
2、ListView中的notifyDataSetChanged()方法
Windows事件監聽機制就是發布-訂閱模型
Windows桌面軟件一旦打開,都在監聽鼠標,鍵盤等輸入設備給他傳遞的信息。下面的代碼舉了同時打開了PS和Word,監聽輸入事件為例子:
public class Software implements Observer {
public String softwareName;
public Software(String softwareName) {
this.softwareName = softwareName;
}
@Override
public void update(Observable o,Object arg) {
System.out.println(arg+"進行判斷改事件是否操作于"+softwareName);
}
@Override
public String toString() {
return "軟件名:"+softwareName;
}
}
public class WindowsEventListener extends Observable {
public void postEvent(String content) {
setChanged();
notifyObservers(content);
}
}
public class Main {
public static void main(String[] args) {
// 被觀察者
WindowsEventListener wel = new WindowsEventListener();
// 觀察者
Software PS = new Software("PS");
Software Word = new Software("Word");
wel.addObserver(PS);
wel.addObserver(Word);
wel.postEvent("發生鼠標事件");
wel.postEvent("發生鍵盤事件");
}
}
/* 輸出
發生鼠標事件,Word進行判斷這一事件是否操作于自身
發生鼠標事件,PS進行判斷這一事件是否操作于自身
發生鍵盤事件,Word進行判斷這一事件是否操作于自身
發生鍵盤事件,PS進行判斷這一事件是否操作于自身
*/
參考文獻
1、設計模式|菜鳥教程:https://www.runoob.com/design-pattern/design-pattern-tutorial.html
2、《Android源碼設計模式解析與實戰》何紅輝,關愛民著
3、隔壁老李頭:http://www.lxweimin.com/p/82f74db14a18