上一篇 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、隔壁老李头:https://www.jianshu.com/p/82f74db14a18
网友评论