Android 網(wǎng)絡(luò)框架--Retrofit2 架構(gòu)分析

面向接口編程

面向接口編程户魏,模塊化編程的必備技能,其乃實(shí)現(xiàn)解耦呻征,增強(qiáng)擴(kuò)展性的重要手段耘婚。

面向接口編程具體指的是什么呢?

首先說(shuō)一下什么是面向?qū)ο缶幊搪礁常蠹叶贾楞宓唬嫦驅(qū)ο缶幊淌窍鄬?duì)于面向過(guò)程編程來(lái)說(shuō)的,基本上攒岛,具有對(duì)象概念的程序設(shè)計(jì)都可以稱為面向?qū)ο缶幊汤盗佟6嫦蚪涌诰幊虄H僅是面向?qū)ο缶幊痰囊环N模塊化實(shí)現(xiàn)形式,其從組件的角度來(lái)進(jìn)行代碼設(shè)計(jì)灾锯,將抽象與實(shí)現(xiàn)分離兢榨。

接口泛指實(shí)體把自己提供給外界的一種抽象物,利用由內(nèi)部操作分離出的外部溝通方法顺饮,使得實(shí)體能被修改內(nèi)部而不影響外界其他實(shí)體與自己交互的方式色乾。面向接口編程中的“接口”,在Java語(yǔ)言中领突,不僅僅是“interface”關(guān)鍵字這么簡(jiǎn)單暖璧,interface、abstract class以及普通的class都能成為所謂的接口君旦。

interface約定的是務(wù)必實(shí)現(xiàn)的方法澎办,強(qiáng)調(diào)的是規(guī)則的制定嘲碱。abstract class則是在抽象的同時(shí)允許提供一些默認(rèn)的行為,以達(dá)到代碼復(fù)用的效果局蚀。一個(gè)實(shí)現(xiàn)類(相對(duì)于抽象而言)可以實(shí)現(xiàn)多個(gè)interface麦锯,而只能繼承一個(gè)abstract class。

面向接口編程能夠帶來(lái)什么呢琅绅?

面向接口編程可以降低代碼間的耦合扶欣,增強(qiáng)代碼的擴(kuò)展性,而正是這種特性千扶,使得多人同時(shí)開(kāi)發(fā)變成了可能料祠。其實(shí)大部分設(shè)計(jì)模式就是面向接口編程很好的例子。

面向接口編程如何實(shí)現(xiàn)呢澎羞?

進(jìn)行面向接口編程實(shí)操時(shí)髓绽,我們一般注意三點(diǎn):先定義接口(接口或者抽象類),再定義實(shí)現(xiàn)類妆绞;在函數(shù)間傳入傳出的是接口而不是實(shí)現(xiàn)類顺呕;一方只認(rèn)識(shí)另一方的接口,想進(jìn)入另一方括饶,就去調(diào)用另一方所披上的接口外套株茶。

從下圖中我們可以看到Retrofit用到了哪些接口類:


Retrofit接口類.png

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

我們從Retrofit的調(diào)用流程來(lái)分析用到的設(shè)計(jì)模式

創(chuàng)建Retrofit對(duì)象

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(API_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .build();

建造者模式--摘自《Java與模式》
建造者模式可以將一個(gè)產(chǎn)品的內(nèi)部表象與產(chǎn)品的生成過(guò)程分割開(kāi)來(lái),從而可以使一個(gè)建造過(guò)程生成具有不同的內(nèi)部表象的產(chǎn)品對(duì)象图焰。
在很多情況下启盛,建造者模式實(shí)際上是將一個(gè)對(duì)象的性質(zhì)建造過(guò)程外部化到獨(dú)立的建造者對(duì)象中,并通過(guò)一個(gè)導(dǎo)演者角色對(duì)這些外部化的性質(zhì)賦值過(guò)程進(jìn)行協(xié)調(diào)楞泼。

以下情況使用建造者模式

  • 需要生成的產(chǎn)品對(duì)象有復(fù)雜的內(nèi)部結(jié)構(gòu)
  • 需要生成的產(chǎn)品對(duì)象的屬性相互依賴
  • 需要生成的產(chǎn)品對(duì)象有多個(gè)可選的構(gòu)造參數(shù)
  • 防止生成的產(chǎn)品對(duì)象的參數(shù)被再次修改

創(chuàng)建網(wǎng)絡(luò)請(qǐng)求接口的實(shí)例

GitHub github = retrofit.create(GitHub.class);

門面模式--摘自《Java與模式》
門面模式要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信必須通過(guò)一個(gè)統(tǒng)一的門面(Facade)對(duì)象進(jìn)行驰徊,門面提供一個(gè)高層次的接口笤闯,使得子系統(tǒng)更易于使用
門面模式的門面類將客戶端與子系統(tǒng)的內(nèi)部復(fù)雜性分隔開(kāi)堕阔,使得客戶端只需要與門面對(duì)象打交道,而不需要與子系統(tǒng)內(nèi)部的很多對(duì)象打交道

以下情況使用門面模式

  • 為了使得子系統(tǒng)更具可復(fù)用性時(shí)颗味,可以使用Facade模式為一個(gè)復(fù)雜子系統(tǒng)提供一個(gè)簡(jiǎn)單接口
  • 為了得到子系統(tǒng)獨(dú)立性和可移植性時(shí)超陆,可以使用Facade模式將一個(gè)子系統(tǒng)與他的客戶端以及其他子系統(tǒng)分離
  • 在構(gòu)建一個(gè)層次化的系統(tǒng)時(shí),可以使用Facade模式定義系統(tǒng)中每一層的入口

創(chuàng)建網(wǎng)絡(luò)請(qǐng)求接口中方法的Call實(shí)例

代碼塊一
Call<List<Contributor>> call = github.contributors("square", "retrofit");
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
    throws Throwable {
  // If the method is a method from Object then defer to normal invocation.
  if (method.getDeclaringClass() == Object.class) {
    return method.invoke(this, args);
  }
  if (platform.isDefaultMethod(method)) {
    return platform.invokeDefaultMethod(method, service, proxy, args);
  }
  ServiceMethod<Object, Object> serviceMethod =
      (ServiceMethod<Object, Object>) loadServiceMethod(method);
  OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
  return serviceMethod.callAdapter.adapt(okHttpCall);
}

代理模式(本代碼塊為動(dòng)態(tài)代理)--摘自《Java與模式》
代理主題并不改變主題的接口浦马,因?yàn)槟J降挠靡馐遣蛔尶蛻舳烁杏X(jué)到代理的存在
代理使用委派將客戶端的調(diào)用委派給真實(shí)的主題對(duì)象时呀,換言之,代理主題起到的是一個(gè)傳遞請(qǐng)求的作用
代理主題在傳遞請(qǐng)求之前和之后都可以執(zhí)行特定的操作晶默,而不是單純傳遞請(qǐng)求

以下情況使用代理模式

  • 遠(yuǎn)程代理:系統(tǒng)可以將網(wǎng)絡(luò)的細(xì)節(jié)隱藏起來(lái)谨娜,使得客戶端不必考慮網(wǎng)絡(luò)的存在
  • 虛擬代理:代理對(duì)象可以在必要的時(shí)候才將被代理的對(duì)象加載
  • 保護(hù)代理:在運(yùn)行時(shí)間對(duì)用戶的相關(guān)權(quán)限進(jìn)行檢查,然后在核實(shí)后決定是否將調(diào)用傳遞給被代理的對(duì)象
  • 智能引用代理:在訪問(wèn)一個(gè)對(duì)象時(shí)可以執(zhí)行一些內(nèi)務(wù)處理操作磺陡,比如計(jì)數(shù)或者日志操作
代碼塊二
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
  int start = adapterFactories.indexOf(skipPast) + 1;
  for (int i = start, count = adapterFactories.size(); i < count; i++) {
    CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
    if (adapter != null) {
      return adapter;
    }
  }

策略模式--摘自《Java與模式》
其是對(duì)算法的包裝趴梢,是把使用算法的責(zé)任和算法本身分隔開(kāi)漠畜,委派給不同的對(duì)象管理。
其通常把一個(gè)系列的算法包裝到一系列的策略類里面坞靶,作為一個(gè)抽象策略類的子類憔狞。即,準(zhǔn)備一組算法彰阴,并將每個(gè)算法封裝到具有共同接口的獨(dú)立的類中瘾敢,使得它們可以互換。
其并不決定在何時(shí)使用何種算法尿这,應(yīng)當(dāng)由客戶端自己決定在什么情況下使用什么具體策略角色簇抵。

以下情況使用策略模式

  • 一個(gè)系統(tǒng)中有許多類,而它們的區(qū)別僅在于它們的行為
  • 一個(gè)系統(tǒng)需要?jiǎng)討B(tài)的在幾種算法中選擇一種
  • 一個(gè)系統(tǒng)的算法使用的數(shù)據(jù)不可以讓客戶端知道
  • 一個(gè)對(duì)象有很多的行為妻味,如果不用恰當(dāng)?shù)哪J秸梗@些行為就只好使用多重的條件選擇語(yǔ)句來(lái)實(shí)現(xiàn),而此時(shí)可以考慮使用策略模式來(lái)解決责球。
代碼塊三
return new CallAdapter<Object, Call<?>>() {
  @Override public Type responseType() {
    return responseType;
  }

  @Override public Call<Object> adapt(Call<Object> call) {
    return new ExecutorCallbackCall<>(callbackExecutor, call);
  }
};

@Override public Object adapt(Call<R> call) {
  OnSubscribe<Response<R>> callFunc = isAsync
      ? new CallEnqueueOnSubscribe<>(call)
      : new CallExecuteOnSubscribe<>(call);

  OnSubscribe<?> func;
  if (isResult) {
    func = new ResultOnSubscribe<>(callFunc);
  } else if (isBody) {
    func = new BodyOnSubscribe<>(callFunc);
  } else {
    func = callFunc;
  }
  Observable<?> observable = Observable.create(func);

  if (scheduler != null) {
    observable = observable.subscribeOn(scheduler);
  }

  if (isSingle) {
    return observable.toSingle();
  }
  if (isCompletable) {
    return observable.toCompletable();
  }
  return observable;
}

適配器模式--摘自《Java與模式》
把一個(gè)類的接口變換成客戶端所期待的另一種接口焦履,從而使原本因接口不匹配而無(wú)法在一起工作的兩個(gè)類能夠在一起工作。

以下情況使用適配器模式

  • 系統(tǒng)需要使用現(xiàn)有的類雏逾,而此類的接口不符合系統(tǒng)的需要
  • 想要建立一個(gè)可以重復(fù)使用的類嘉裤,用于與一些彼此之間沒(méi)有太大關(guān)聯(lián)的一些類(包括一些可能在將來(lái)引進(jìn)的類)一起工作

發(fā)送網(wǎng)絡(luò)請(qǐng)求

static final class ExecutorCallbackCall<T> implements Call<T> {
  final Executor callbackExecutor;
  final Call<T> delegate; //注意,變量類型是父類的類型

  ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
    this.callbackExecutor = callbackExecutor;
    this.delegate = delegate;
  }

  @Override public void enqueue(final Callback<T> callback) {
    checkNotNull(callback, "callback == null");
 
    delegate.enqueue(new Callback<T>() {
      @Override public void onResponse(Call<T> call, final Response<T> response) {
        callbackExecutor.execute(new Runnable() {
          @Override public void run() {
            if (delegate.isCanceled()) {
              // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
              callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
            } else {
              callback.onResponse(ExecutorCallbackCall.this, response);
            }
          }
        });
      }

      @Override public void onFailure(Call<T> call, final Throwable t) {
        callbackExecutor.execute(new Runnable() {
          @Override public void run() {
            callback.onFailure(ExecutorCallbackCall.this, t);
          }
        });
      }
    });
  }
}

裝飾模式--摘自《Java與模式》
以對(duì)客戶透明的方式動(dòng)態(tài)地給一個(gè)對(duì)象附加上更多的責(zé)任栖博。換言之屑宠,客戶端并不會(huì)覺(jué)得對(duì)象在裝飾前和裝飾后有什么不同
可以在不使用創(chuàng)造更多子類的情況下,將對(duì)象的功能加以擴(kuò)展仇让,是繼承關(guān)系的一個(gè)替代方案
純粹的裝飾模式很難找到典奉,裝飾模式用意在不改變接口的前提下,增強(qiáng)被裝飾類的性能丧叽,即要滿足透明性卫玖。在增強(qiáng)性能的時(shí)候,往往需要建立新的公開(kāi)方法踊淳。這就導(dǎo)致了大多數(shù)的裝飾模式的實(shí)現(xiàn)都是“半透明”的假瞬。這意味著客戶端不去聲明抽象父類類型的變量,而是聲明具體裝飾類類型的變量迂尝,從而可以調(diào)用具體裝飾類中才有的方法脱茉。

以下情況使用裝飾模式

  • 需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類增加附加責(zé)任
  • 需要?jiǎng)討B(tài)地給一個(gè)對(duì)象增加功能垄开,這些功能可以再動(dòng)態(tài)地撤銷
  • 需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能琴许,從而使繼承關(guān)系變得不現(xiàn)實(shí)

對(duì)于這一塊代碼,網(wǎng)絡(luò)上也有人將其歸類為代理模式溉躲,本獸下面說(shuō)一下自己的觀點(diǎn)榜田。
裝飾模式寸认、適配器模式、代理模式都是包裝(Wrapper)模式串慰,首先說(shuō)一下他們之間的區(qū)別偏塞。

  • 裝飾模式&適配器模式:適配器模式把一個(gè)API轉(zhuǎn)換成另一個(gè)API,而裝飾模式是保持被包裝的對(duì)象的API邦鲫。用Java術(shù)語(yǔ)來(lái)講灸叼,適配器和被適配的類實(shí)現(xiàn)的是不同的接口和抽象類,而裝飾模式和被裝飾的類實(shí)現(xiàn)的是相同的接口和抽象類庆捺。半透明的裝飾模式實(shí)際上就是處于在適配器模式與裝飾模式之間的灰色地帶古今。
  • 裝飾模式&代理模式:兩種模式相同點(diǎn)都是保持被包裝的對(duì)象的API。但是滔以,裝飾模式為所裝飾的對(duì)象提供增強(qiáng)功能捉腥,而代理模式則為所代理對(duì)象的使用施加控制。

本獸認(rèn)為你画,這一塊代碼抵碟,將其歸類為裝飾模式或者代理模式,都是可以的坏匪。因?yàn)樵O(shè)計(jì)模式本就是屬于概念性的拟逮,指導(dǎo)性的范疇,各個(gè)設(shè)計(jì)模式其實(shí)沒(méi)有那么清晰的界限适滓,沒(méi)必要非要分個(gè)你清我楚敦迄,只要都滿足基本的設(shè)計(jì)原則(S.O.L.I.D)即可。

但如果非要較真(程序員的特點(diǎn))凭迹,到底偏向于裝飾模式還是偏向于代理模式罚屋,本獸認(rèn)為其更偏向于裝飾模式,進(jìn)一步來(lái)講嗅绸,其更偏向于簡(jiǎn)化后的裝飾模式脾猛。

裝飾模式簡(jiǎn)易類圖如下:


裝飾模式簡(jiǎn)略類圖.png

簡(jiǎn)化后的裝飾模式簡(jiǎn)易類圖如下:


簡(jiǎn)化后的裝飾模式簡(jiǎn)易類圖.png

代理模式簡(jiǎn)易類圖如下:


代理模式簡(jiǎn)易類圖.png

大家可以看到,簡(jiǎn)化后的裝飾模式的簡(jiǎn)易類圖和代理模式的簡(jiǎn)易類圖朽砰,非常相像尖滚。相比較之后喉刘,不同點(diǎn)如下:

  • 裝飾類含有的變量的類型瞧柔,是父類的類型,而這個(gè)變量本身一般就是左側(cè)的被裝飾類的實(shí)例
  • 代理類含有的變量的類型睦裳,直接就是左側(cè)被代理類的類型造锅,從而這個(gè)變量本身必然是左側(cè)被代理類的實(shí)例

根據(jù)上述區(qū)別,再對(duì)應(yīng)到代碼塊廉邑,我們就可以得出結(jié)論哥蔚,其更偏向于簡(jiǎn)化后的裝飾模式倒谷。

處理返回?cái)?shù)據(jù)

NA

總結(jié)

Retrofit更像是一個(gè)組織者,他把幾個(gè)框架高效的組合起來(lái)糙箍,在解耦的同時(shí)也滿足了擴(kuò)展性:其利用OkHTTP進(jìn)行網(wǎng)絡(luò)請(qǐng)求渤愁;與異步請(qǐng)求框架和類解析框架解耦,使得Retrofit可以適配多種框架深夯,使用者可以輕松的選擇或者自創(chuàng)適合自己項(xiàng)目的異步請(qǐng)求和解析的框架抖格。

讀者可以好好體會(huì)一下其是如何玩轉(zhuǎn)各種設(shè)計(jì)模式,把面向接口編程發(fā)揮得淋漓盡致的咕晋。

Retrofit 2.0之后網(wǎng)絡(luò)只支持OKHttp雹拄,對(duì)OKHttp強(qiáng)依賴。以后如果有新的網(wǎng)絡(luò)框架出現(xiàn)掌呜,將無(wú)法使Retrofit滓玖。但是Retrofit提供的封裝網(wǎng)絡(luò)框架的思路依然值得借鑒。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末质蕉,一起剝皮案震驚了整個(gè)濱河市势篡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌模暗,老刑警劉巖殊霞,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異汰蓉,居然都是意外死亡绷蹲,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門顾孽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)祝钢,“玉大人,你說(shuō)我怎么就攤上這事若厚±褂ⅲ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵测秸,是天一觀的道長(zhǎng)疤估。 經(jīng)常有香客問(wèn)我,道長(zhǎng)霎冯,這世上最難降的妖魔是什么铃拇? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮沈撞,結(jié)果婚禮上慷荔,老公的妹妹穿的比我還像新娘。我一直安慰自己缠俺,他們只是感情好显晶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布贷岸。 她就那樣靜靜地躺著,像睡著了一般磷雇。 火紅的嫁衣襯著肌膚如雪偿警。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天唯笙,我揣著相機(jī)與錄音户敬,去河邊找鬼。 笑死睁本,一個(gè)胖子當(dāng)著我的面吹牛尿庐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呢堰,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼抄瑟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了枉疼?” 一聲冷哼從身側(cè)響起皮假,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎骂维,沒(méi)想到半個(gè)月后惹资,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡航闺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年褪测,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片潦刃。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侮措,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乖杠,到底是詐尸還是另有隱情分扎,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布胧洒,位于F島的核電站畏吓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏卫漫。R本人自食惡果不足惜菲饼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汛兜。 院中可真熱鬧巴粪,春花似錦通今、人聲如沸粥谬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)漏策。三九已至派哲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掺喻,已是汗流浹背芭届。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留感耙,地道東北人褂乍。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像即硼,于是被迫代替她去往敵國(guó)和親逃片。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,077評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理只酥,服務(wù)發(fā)現(xiàn)褥实,斷路器,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • 第一天僻澎,久違的寒假班的感覺(jué)。似乎又找到一些上課的熱情十饥,雖然還是靠著之前的功力+臨場(chǎng)發(fā)揮怎棱,但還算是湊合著。 ...
    鳴人君不見(jiàn)子閱讀 140評(píng)論 0 0
  • 七月的城市 執(zhí)著與迷惘 沒(méi)有盡頭地等待 看不見(jiàn)未來(lái)的期許 焦灼 慵懶的小貓 和連綿不斷的雨 齊齊來(lái)敲窗 這個(gè)夏天 ...
    夢(mèng)槿馨閱讀 141評(píng)論 0 1
  • 春天來(lái)了绷跑,春天意味著什么拳恋,提到春天大家腦海中第一印象又是什么,大家可能都有自己的想法砸捏,有人覺(jué)得春天是萬(wàn)物復(fù)蘇的季節(jié)...
    小豬de腳印閱讀 208評(píng)論 0 0