一日一學(xué)_okhttp(設(shè)計(jì)模式)

OkHttp 源碼中設(shè)計(jì)模式還是值得我學(xué)習(xí)借鑒的俯逾。

OkHttp設(shè)計(jì)模式

源碼分析:http://blog.piasy.com/2016/07/11/Understand-OkHttp/#section-2
這位作者大大佩抹,分析很棒(我只是在他的基礎(chǔ)上學(xué)習(xí)擴(kuò)展下下)

public OkHttpClient() {  
   this(new Builder());
}
public Builder() {
  dispatcher = new Dispatcher();
  protocols = DEFAULT_PROTOCOLS;
  connectionSpecs = DEFAULT_CONNECTION_SPECS;
  proxySelector = ProxySelector.getDefault();
  cookieJar = CookieJar.NO_COOKIES;
  socketFactory = SocketFactory.getDefault();
  hostnameVerifier = OkHostnameVerifier.INSTANCE;
  certificatePinner = CertificatePinner.DEFAULT;
  proxyAuthenticator = Authenticator.NONE;
  authenticator = Authenticator.NONE;
  connectionPool = new ConnectionPool();
  dns = Dns.SYSTEM;
  followSslRedirects = true;
  followRedirects = true;
  retryOnConnectionFailure = true;
  connectTimeout = 10_000;
  readTimeout = 10_000;
  writeTimeout = 10_000;
}

對(duì)象創(chuàng)建型模式(Builder模式)
使用Builder模式處理需要很多參數(shù)的構(gòu)造函數(shù)芯咧,提高代碼可讀性巢音。(Builder模式的優(yōu)點(diǎn))
下面例子比較可以很好理解Builder模式的好處痴奏。
本地緩存對(duì)象構(gòu)造對(duì)比:

//如果這樣構(gòu)造對(duì)象可讀性很差裸违,雖然實(shí)現(xiàn)了功能
RxCache rxCache = new RxCache(new File(getCacheDir().getPath() + File.separator + "data-wuxiao"),
new DiskConverter(),2*1024*1024,40*1024*1024)

使用Builder模式

RxCache rxCache = new RxCache.Builder()
                .diskDir(new File(getCacheDir().getPath() + File.separator + "data-wuxiao"))
                .diskConverter(new DiskConverter())
                .memory(2*1024*1024)
                .disk(40*1024*1024)
                .build();

總結(jié):
構(gòu)建對(duì)象時(shí)湃鹊,如果碰到類有很多參數(shù)——其中很多參數(shù)類型相同而且很多參數(shù)可以為空時(shí),我更喜歡Builder模式來(lái)完成。如參數(shù)數(shù)量不多后豫、類型不同實(shí)現(xiàn)Builder并體現(xiàn)不出它的優(yōu)勢(shì)(傳統(tǒng)的構(gòu)造函數(shù)則更加優(yōu)勢(shì))悉尾。

OkHttp - Interceptor責(zé)任鏈模式

Interceptor是 OkHttp 核心類,它把網(wǎng)絡(luò)請(qǐng)求挫酿、緩存构眯、透明壓縮等功能都統(tǒng)一了起來(lái),每一個(gè)功能都是一個(gè) Interceptor早龟,它們?cè)龠B接成一個(gè) Interceptor.Chain惫霸,如鏈條一般,分工明確葱弟,完美完成一次網(wǎng)絡(luò)請(qǐng)求壹店。

private Response getResponseWithInterceptorChain() throws IOException {
  // Build a full stack of interceptors.
  List<Interceptor> interceptors = new ArrayList<>();
  interceptors.addAll(client.interceptors());
  interceptors.add(retryAndFollowUpInterceptor);
  interceptors.add(new BridgeInterceptor(client.cookieJar()));
  interceptors.add(new CacheInterceptor(client.internalCache()));
  interceptors.add(new ConnectInterceptor(client));
  if (!retryAndFollowUpInterceptor.isForWebSocket()) {
    interceptors.addAll(client.networkInterceptors());
  }
  interceptors.add(new CallServerInterceptor(
      retryAndFollowUpInterceptor.isForWebSocket()));

  Interceptor.Chain chain = new RealInterceptorChain(
      interceptors, null, null, null, 0, originalRequest);
  return chain.proceed(originalRequest);
}

責(zé)任鏈其實(shí)在Android應(yīng)用也存在(如:事件傳遞就是責(zé)任鏈機(jī)制)。
那么它在Android中是如何使用?


提示框例子.jpg

有時(shí)界面上會(huì)彈出好幾個(gè)這種臨時(shí)顯示的窗體或者控件芝加,它們只是為了顯示一下硅卢,然后需要用戶關(guān)閉,常常我們希望可以按下返回鍵將它們關(guān)閉妖混。
一般會(huì)寫如下代碼:

      //這種也算是責(zé)任鏈的簡(jiǎn)單體現(xiàn)
      if(viewA.isShow()){
            viewA.dismiss();
        }else if(viewB.isShow()){
            viewB.dismiss();
       }
      .....

如果只有一兩個(gè)老赤,這么寫還可以。但如果情況復(fù)雜了的話制市,這么寫抬旺,設(shè)計(jì)上就會(huì)很糟糕。在這種情況下使用責(zé)任鏈模式來(lái)處理會(huì)更優(yōu)一些祥楣。
我們以一個(gè)簡(jiǎn)單例子來(lái)證明這種設(shè)計(jì)模式的好處:
IStatus這個(gè)接口用于交互布局的狀態(tài)(顯示或者隱藏):

public interface IStatus<T> {
    public boolean onStatus(@NonNull T status);
}

ViewStatus類對(duì)IStatus接口進(jìn)行了初步實(shí)現(xiàn)开财,它是布局交互的核心。它會(huì)首先詢問(wèn)自己是否顯示(隱藏)布局 误褪,否則的話會(huì)交給下個(gè)布局责鳍。


public abstract class ViewStatus<T> implements IStatus<T> {
 protected IStatus mViewStatus;
    protected T view;

    /**
     * @param mViewStatus 下一個(gè)狀態(tài)對(duì)象的接受者
     * @param view   下一個(gè)view
     */
    public ViewStatus(IStatus mViewStatus, T view) {
        this.mViewStatus = mViewStatus;
        this.view = view;
    }

    @Override
    public boolean onStatus(@NonNull T status) {
        boolean isStatus = onStatusImpl(status);
        if (!isStatus && mViewStatus != null)
            return mViewStatus.onStatus(view);
        return isStatus;
    }

    /**
     * @param status
     * @return 代表view狀態(tài)是否顯示
     */
    protected abstract boolean onStatusImpl(@NonNull T status);
}

隱藏view

public class InVisibleViewStatus extends ViewStatus<View> {

    public InVisibleViewStatus(IStatus mViewStatus, View view) {
        super(mViewStatus, view);
    }

    @Override
    public boolean onStatusImpl(@NonNull View status) {
        View tempView = status;
        if (tempView.getVisibility() == View.VISIBLE) {
            tempView.setVisibility(View.INVISIBLE);
            return true;
        }
        return false;
    }

用于View顯示隱藏的Demo

        view_1 = findViewById(R.id.view1);
        view_2 = findViewById(R.id.view2);
        view_3 = findViewById(R.id.view3);
        view_4 = findViewById(R.id.view4);

        //生成事件處理責(zé)任鏈,startViewStatus為鏈頭,處理順序由外向內(nèi)
        ViewStatus viewStatus3 = new VisibleViewStatus(null, null);
        ViewStatus viewStatus2 = new InVisibleViewStatus(viewStatus3, view_4);
        ViewStatus viewStatus1 = new InVisibleViewStatus(viewStatus2, view_3);
        startViewStatus = new InVisibleViewStatus(viewStatus1, view_2);
        findViewById(R.id.back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startViewStatus.onStatus(view_1);
            }
        });
  • 演示


    布局隱藏與顯示

責(zé)任鏈模式demo地址:https://github.com/quiet-wuxiao/ResponsibilityChainDemo

總結(jié):責(zé)任鏈模式優(yōu)點(diǎn)可以對(duì)請(qǐng)求者和處理者關(guān)系的解耦提高代碼的靈活性兽间,如果在上面例子中再添加個(gè)view動(dòng)畫的特效历葛,僅僅需要繼承ViewStatus進(jìn)行動(dòng)畫添加就可以,已存在類都可保持不變嘀略。責(zé)任鏈模式的最大缺點(diǎn)是對(duì)鏈中布局對(duì)象的遍歷恤溶,如果布局對(duì)象太多那么遍歷必定會(huì)影響性能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末帜羊,一起剝皮案震驚了整個(gè)濱河市咒程,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌讼育,老刑警劉巖帐姻,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稠集,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡饥瓷,警方通過(guò)查閱死者的電腦和手機(jī)剥纷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扛伍,“玉大人筷畦,你說(shuō)我怎么就攤上這事〈倘鳎” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵吼砂,是天一觀的道長(zhǎng)逆航。 經(jīng)常有香客問(wèn)我,道長(zhǎng)渔肩,這世上最難降的妖魔是什么因俐? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮周偎,結(jié)果婚禮上抹剩,老公的妹妹穿的比我還像新娘。我一直安慰自己蓉坎,他們只是感情好澳眷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛉艾,像睡著了一般钳踊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勿侯,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天拓瞪,我揣著相機(jī)與錄音,去河邊找鬼助琐。 笑死祭埂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兵钮。 我是一名探鬼主播蛆橡,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼矢空!你這毒婦竟也來(lái)了航罗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤屁药,失蹤者是張志新(化名)和其女友劉穎粥血,沒(méi)想到半個(gè)月后柏锄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡复亏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年趾娃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缔御。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抬闷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耕突,到底是詐尸還是另有隱情笤成,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布眷茁,位于F島的核電站炕泳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏上祈。R本人自食惡果不足惜培遵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望登刺。 院中可真熱鬧籽腕,春花似錦、人聲如沸纸俭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)掉蔬。三九已至廊宪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間女轿,已是汗流浹背箭启。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛉迹,地道東北人傅寡。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像北救,于是被迫代替她去往敵國(guó)和親荐操。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,072評(píng)論 25 707
  • 這段時(shí)間老李的新公司要更換網(wǎng)絡(luò)層珍策,知道現(xiàn)在主流網(wǎng)絡(luò)層的模式是RxJava+Retrofit+OKHttp,所以老李...
    隔壁老李頭閱讀 32,776評(píng)論 51 406
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理托启,服務(wù)發(fā)現(xiàn),斷路器攘宙,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • OkHttp解析系列 OkHttp解析(一)從用法看清原理OkHttp解析(二)網(wǎng)絡(luò)連接OkHttp解析(三)關(guān)于...
    Hohohong閱讀 20,974評(píng)論 4 58
  • 文/段曉艾 生活中,有的家庭重視親子關(guān)系疗绣,特別是母親在有了孩子之后线召,全身心的投入到照顧孩子上,而忽略了丈夫多矮。 面對(duì)...
    段曉艾閱讀 1,049評(píng)論 0 0