文章摘要
1伟端、針對接口搭建的框架却舀,才能更好的兼容變化。
2肺稀、volley中那些設(shè)計原則以及模式的身影。
附:獲取Volley源代碼
Demos案例源碼:https://github.com/HailouWang/DemosForApi
從今天開始应民,會陸續(xù)介紹下Volley中那些實現(xiàn)機制以及設(shè)計模式话原,也歡迎大家將Volley的使用心得或者疑問發(fā)出來,大家一起Level Up ~
一诲锹、綜述
針對 接口/超類型 編程繁仁,會讓程序更好的兼容變化。這條設(shè)計原則归园,貫穿Volley工作流程實現(xiàn)的始終黄虱。我們可以數(shù)一下:
- 1、Request:新建一個請求庸诱,不同的請求捻浦,不同的數(shù)據(jù)解析方法晤揣。
- 2、Cache:緩存的處理朱灿,不同的處理昧识,不同的子類來實現(xiàn)。
- 3母剥、Network:解析網(wǎng)絡(luò)數(shù)據(jù)滞诺。如果服務(wù)器有特定配置,可實現(xiàn)特定解析子類环疼。
- 4习霹、HttpStack:網(wǎng)絡(luò)請求發(fā)送以及處理。不同的瀏覽器/不同的服務(wù)器炫隶,如果存在不同淋叶,提供了HurlStack、HttpClientStack不同的實現(xiàn)伪阶。
- 5煞檩、RetryPolicy:請求失敗重試策略,可以針對具體的請求栅贴,實現(xiàn)自己的重試策略斟湃。
二、框架中的設(shè)計略影~
前面的幾篇檐薯,有些來自官網(wǎng)的Demos凝赛,有些來自作者自己編寫的案例,從整體上介紹了Volley的工作流程以及實現(xiàn)邏輯坛缕。同時墓猎,Volley作為一個短小但能力精悍的框架,還讓我們可以從中汲取更多設(shè)計的營養(yǎng)赚楚,從設(shè)計模式的角度毙沾,包括但不限于:
- 1、設(shè)計原則:針對接口(超類型)編程宠页,而不是針對實現(xiàn)編程左胞。
- 在Volley中,網(wǎng)絡(luò)請求封裝成Request(Request是一個超類型)举户。
- 在Volley中烤宙,Request通過分發(fā),首先需要從緩沖中去檢索敛摘,不存在再去網(wǎng)絡(luò)上同步。在此處所有的實現(xiàn)乳愉,針對的是Cache/Network接口兄淫,例如:NetworkDispatcher屯远,組合引用了Cache/Network,而不是他們的實現(xiàn)類捕虽。
public class NetworkDispatcher extends Thread {
/** The queue of requests to service. */
private final BlockingQueue<Request<?>> mQueue;
/** The network interface for processing requests. */
private final Network mNetwork;
/** The cache to write to. */
private final Cache mCache;
- 2慨丐、設(shè)計原則:找出應(yīng)用中可能需要變化的類,把他們獨立出來泄私,不要和那些不需要變化的代碼混在一起房揭。
如果代碼中,每次需求已更新晌端,都會使某方面的代碼發(fā)生變化捅暴,那么我們即可以肯定,這部分代碼應(yīng)該被處理出來咧纠,和其他代碼有所區(qū)分蓬痒。
例如:Request為什么要那么多的實現(xiàn)類?
Request實現(xiàn)類
- 3漆羔、策略模式:定義了算法簇梧奢,分別封藏起來,讓他們之間可以互相替換演痒,此模式讓算法的變化獨立于使用算法的客戶亲轨。
HttpStack stack 是一個接口,定義了performRequest方法鸟顺,用于真正和網(wǎng)絡(luò)處理數(shù)據(jù)惦蚊,不同的Android平臺的設(shè)備,處理邏輯不同诊沪。組合接口的好處就是可以方便在不同的設(shè)備間切換养筒。
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}