Code Complete — 代碼改善

代碼改善的目的是為了提高質(zhì)量席爽,這個(gè)質(zhì)量不僅包括從用戶角度出發(fā)的軟件質(zhì)量意荤,也包括從開發(fā)者角度出發(fā)的代碼質(zhì)量。

軟件質(zhì)量的普遍原理就是改善質(zhì)量以降低開發(fā)成本只锻。提高生產(chǎn)效率和改善質(zhì)量的最佳途徑就是減少花在這種代碼返工上得時(shí)間玖像,無論返工是由需求、設(shè)計(jì)改變還是調(diào)試引起的齐饮。?提高質(zhì)量的方式有協(xié)同構(gòu)建捐寥、調(diào)試與測試、代碼重構(gòu)和調(diào)整等多種方式祖驱,本文記錄了一些主要策略握恳。

協(xié)同構(gòu)建

協(xié)同開發(fā)實(shí)踐往往能比測試發(fā)現(xiàn)更多的缺陷,并且更有效率捺僻。

“協(xié)同構(gòu)建”包括結(jié)對編程乡洼、正式檢查、非正式技術(shù)復(fù)查、文檔閱讀就珠,以及其他讓開發(fā)者共同承擔(dān)創(chuàng)建代碼及其它工作產(chǎn)品責(zé)任的技術(shù)寇壳。結(jié)對編程成本太高,代碼審查倒是非常普遍妻怎。

不得不說“協(xié)同構(gòu)建”是確保軟件質(zhì)量的有效途徑壳炎,結(jié)對編程本身有很多好處以及技巧,書中花了大量篇幅來介紹逼侦,但是在國內(nèi)互聯(lián)網(wǎng)公司匿辩,基本上是一個(gè)程序員同時(shí)負(fù)責(zé)好幾個(gè)項(xiàng)目,很難讓兩個(gè)程序員來寫同一份代碼榛丢,因此通過”協(xié)同構(gòu)建”來確保質(zhì)量的重任就落在了代碼審查上面铲球。

代碼走查是比較通俗的說法,細(xì)分的話可分為正式檢查(Formal inspections)晰赞,走查(Walk-Throughs)稼病,代碼閱讀(Code Reading)。

正式檢查過程中掖鱼,每個(gè)人都需要扮演一個(gè)明確的角色:

  • 主持人然走。主持人一般是老手,能hold住場以及控制進(jìn)度戏挡,不能因?yàn)槟承┘?xì)節(jié)問題爭論太久而導(dǎo)致會(huì)議延長芍瑞。審查的主要目的是發(fā)現(xiàn)盡可能多的缺陷,而不是討論技術(shù)問題褐墅。
  • 作者拆檬。作者的首要任務(wù)是向大家清晰的解釋代碼。
  • 評(píng)論員妥凳。評(píng)論員是同設(shè)計(jì)和代碼有直接關(guān)系的人竟贯,但又不是作者,一般不止一個(gè)猾封。
  • 記錄員澄耍。記錄發(fā)現(xiàn)的問題,以及記錄因此而產(chǎn)生的修復(fù)計(jì)劃晌缘。

檢查會(huì)議的準(zhǔn)備工作以及角色指定通常由主持人負(fù)責(zé)齐莲,會(huì)議結(jié)束后主持人/記錄員需要寫一份缺陷報(bào)告,然后作者負(fù)責(zé)修復(fù)缺陷,修復(fù)后由評(píng)論員來審核這些問題磷箕。

代碼走查是一個(gè)很隨意的概念选酗,公司的Code Review大多是這種。走查的所有參與者都會(huì)看代碼并發(fā)現(xiàn)錯(cuò)誤岳枷。走查的重點(diǎn)是檢測錯(cuò)誤芒填,而非修正錯(cuò)誤呜叫。所以一般走查會(huì)議完成后,并沒有專門去檢查最后作者是否將這些缺陷修復(fù)了殿衰。

代碼閱讀就更加靈活了朱庆,就是直接看代碼來發(fā)現(xiàn)問題,通常一個(gè)人就能完成闷祥。雖然檢測出缺陷的概率不如前兩種娱颊,但是對于發(fā)現(xiàn)一些低級(jí)bug還是非常有效的。

測試

測試是改善質(zhì)量最常見的方式凯砍,寫代碼的時(shí)候我們需要單元測試/組件測試/集成測試/回歸測試/系統(tǒng)測試箱硕,有的是程序員完成的,有的是專門測試團(tuán)隊(duì)完成的悟衩。前端的系統(tǒng)化測試流程一直是個(gè)難題剧罩,我們團(tuán)隊(duì)有人在專門研究這塊,此處不作展開座泳。

調(diào)試

調(diào)試是確定錯(cuò)誤根本原因并糾正錯(cuò)誤的過程惠昔,對大部分程序員來說,這可能是開發(fā)中最困難的部分挑势,尤其是在前端舰罚。

不會(huì)調(diào)試的程序員會(huì)受盡bug的折磨,先看下幾種導(dǎo)致調(diào)試效率低下的想法:

  • 憑猜測找出缺陷薛耻。將print,console赏陵,debug散布在程序中饼齿,根據(jù)輸出來找bug:)
  • 只找出問題并用最快的方式修復(fù)它,并不去一探究竟蝙搔。
  • 迷信式調(diào)試缕溉,堅(jiān)信這個(gè)bug不是我造成的,要么是環(huán)境問題吃型,要么是其他程序員造成的证鸥。如果你遇到了這樣的程序員那恭喜你,因?yàn)槟阍僖膊粫?huì)遇到比他更糟的了:)

前端的調(diào)試比后臺(tái)復(fù)雜的多勤晚,不過無論何種程序員應(yīng)該都有一個(gè)共識(shí)枉层,那就是不僅要發(fā)現(xiàn)它,解決它赐写,更要理解它鸟蜡,優(yōu)雅的解決它。

前端調(diào)試發(fā)現(xiàn)的問題多半是兼容問題挺邀,有的是瀏覽器不支持某些屬性造成的揉忘,有的是瀏覽器內(nèi)部機(jī)制造成的跳座,我們需要理解它并且記錄下來,避免下次犯同樣地錯(cuò)誤泣矛。

有一個(gè)問題就是疲眷,我們經(jīng)常會(huì)在周會(huì)里面將自己遇到的一些問題分享出來,避免大家再次采坑您朽,但是分享過后并沒有一個(gè)統(tǒng)一的地方來記錄和歸類這些問題狂丝,之后在遇到類似問題也很難去查周報(bào)記錄,或者有新人進(jìn)來再次犯錯(cuò)的時(shí)候虚倒,它根本不知道這是個(gè)坑美侦,很可能在掉進(jìn)坑之后才意識(shí)到。

尋找缺陷

調(diào)試包含了尋找缺陷和解決缺陷魂奥,通常尋找缺陷并且理解缺陷形成的原因會(huì)占到整個(gè)調(diào)試過程90%的時(shí)間菠剩,只要能重現(xiàn)問題并且發(fā)現(xiàn)原因,修復(fù)工作通常很快耻煤。所以這里重點(diǎn)講下如何優(yōu)雅的尋找缺陷具壮。

首先我覺得應(yīng)該有一個(gè)大致思路:

  1. 出現(xiàn)任何問題首先應(yīng)該審視自己,先檢查是否自己代碼的問題哈蝇;
  2. 如果代碼中沒有發(fā)現(xiàn)問題棺妓,再確認(rèn)一下是否自己的構(gòu)建工具有問題,工具問題需要找維護(hù)工具的開發(fā)者解決炮赦,自己去解決或者規(guī)避非上上策怜跑;
  3. 如果工具也ok那再確定是否電腦環(huán)境的問題,這個(gè)環(huán)境包括了系統(tǒng)本身的host綁定吠勘,網(wǎng)絡(luò)情況性芬,以及依賴庫,或者瀏覽器配置等等剧防,經(jīng)常有人遇到此類情況會(huì)嘗試重啟電腦植锉,有時(shí)還真的管用;
  4. 如果還有問題峭拘,跟你同事確認(rèn)下是不是其他人有發(fā)布相關(guān)代碼俊庇,而這部分代碼剛好影響到你工作了。
  5. 如果還是有問題鸡挠,出去浪一會(huì)兒辉饱,然后再回到步驟1。

然后再重點(diǎn)說下第一點(diǎn)宵凌,畢竟出現(xiàn)問題原因多半在自己鞋囊。首先要優(yōu)雅的找出問題,一定要能夠優(yōu)雅的使用各種調(diào)試工具瞎惫,比如chrome dev tool溜腐,weinre,Safari译株,Charles等,除了知道各種常用技能挺益,深入學(xué)習(xí)還能學(xué)到一些特殊動(dòng)作歉糜,比如我們都會(huì)用Chrome的斷點(diǎn)調(diào)試,但是卻很少用條件斷點(diǎn)望众,然而條件斷點(diǎn)又是一個(gè)很實(shí)用的技能匪补。這些工具和技巧都能讓你更快的發(fā)現(xiàn)問題。

當(dāng)我們遇到問題時(shí)烂翰,控制臺(tái)或者編譯器一般都會(huì)報(bào)錯(cuò)夯缺,我們根據(jù)錯(cuò)誤提示去解決問題。
有時(shí)候js報(bào)錯(cuò)根本就跟錯(cuò)誤代碼沒半毛錢關(guān)系甘耿,兩者差了個(gè)十萬八千米踊兜,而且給出的錯(cuò)誤行數(shù)也并非總是有用,尤其是在壓縮混淆后的代碼佳恬。

針對這種編譯器瞎BB的錯(cuò)誤類型捏境,我們很難直接通過錯(cuò)誤提示找到原因;而更頭疼的時(shí)毁葱,在有的框架里面垫言,你的代碼出問題時(shí)編譯器居然不報(bào)錯(cuò)犹撒!這個(gè)時(shí)候很難從正面去解決問題煤杀,那么就得換一種思路弊决。

  1. 先對你的代碼做語法檢查耗式。如果是方法調(diào)用錯(cuò)誤或者IO錯(cuò)誤的話,提示一般還是很有用的击胜。而某些語法錯(cuò)誤捌浩,比如少個(gè)括號(hào)快集,分號(hào)际度,或者你把某個(gè)單詞拼錯(cuò)了,或者引用包的路徑不對涵妥,或者json配置文件少個(gè)逗號(hào)乖菱,這時(shí)編譯器可能只是進(jìn)行了一些拙劣的掃描,于是便給出了錯(cuò)誤的行號(hào)蓬网。

  2. 如果錯(cuò)誤是最近才出現(xiàn)窒所,或者之前沒有的,直接查看版本歷史記錄帆锋,分析代碼吵取。

  3. 分而治之。 將程序劃分為幾個(gè)模塊锯厢,對這幾個(gè)模塊分別測試或者嘗試注釋掉某個(gè)模塊來逐漸定位問題皮官。

以上是當(dāng)通過編譯器的錯(cuò)誤提示很難找到具體問題時(shí)脯倒,總結(jié)的幾種方法。針對這類問題我還沒有找到一個(gè)很有效的方式捺氢,希望有高人指點(diǎn)藻丢。

修正缺陷

尋找缺陷雖然占了90%的時(shí)間,但是找到問題只是成功了一半摄乒,最終還是要解決問題的悠反。

解決問題的結(jié)果有三種:一是拙劣的解決了問題,二是優(yōu)雅的解決了問題馍佑,三是解決了這個(gè)問題又出現(xiàn)了新的問題斋否!

好吧,這只是經(jīng)驗(yàn)之談拭荤,因?yàn)檫@三類情況我都遇到過茵臭。。穷劈。

第一種情況出現(xiàn)的原因有很多種笼恰,可能是情況緊急,不得已采取的臨時(shí)方案歇终,但是治標(biāo)不治本社证;也可能是沒有理解程序本身,只是解決了某些情況下的問題评凝;也有可能是代碼寫久了自己懵逼了追葡,思維定勢了,出去浪一下說不定就會(huì)想到一個(gè)更優(yōu)雅的解決方案奕短。

第三種情況出現(xiàn)的原因多半是不理解業(yè)務(wù)造成的宜肉。尤其是在修改別人的bug時(shí),一定要保證代碼的侵入性最小翎碑,避免去修改全局變量谬返。而且改完后最好做充分測試。

重構(gòu)

前端技術(shù)發(fā)展飛快日杈,我們昨天使用的技術(shù)遣铝,今天可能就被淘汰了,明天可能又換了新技術(shù)莉擒。Angular火了酿炸,項(xiàng)目用Angular重構(gòu),雙向綁定真是爽涨冀!React火了填硕,又用React重構(gòu)一次,組件化大法好鹿鳖!vue火了扁眯,又開始用vue重構(gòu)壮莹,輕量級(jí)就是靈活!后來WEEX火了...(當(dāng)然實(shí)際情況應(yīng)該不會(huì)如此恋拍,我只是開個(gè)玩笑)

所以說我們最初重構(gòu)的目的是什么垛孔?

當(dāng)然是為了提高質(zhì)量,一方面提高軟件外部表現(xiàn)質(zhì)量施敢,比如性能周荐,穩(wěn)定性等,另一方面提升軟件內(nèi)部質(zhì)量僵娃,比如可維護(hù)性概作,可擴(kuò)展性等。還有一種因素就是業(yè)務(wù)因素默怨,不同的框架適用于不同的業(yè)務(wù)讯榕,如果重構(gòu)使用的新框架能更適合當(dāng)前業(yè)務(wù),那也是極好的匙睹。

不過框架只是包含了特定軟件思想的外殼愚屁,能解決一部分問題,但不能解決代碼本身質(zhì)量問題痕檬。因此拋開框架霎槐,在重構(gòu)時(shí)我們通常要關(guān)注以下點(diǎn)。

  • 重復(fù)代碼梦谜。復(fù)制粘貼即設(shè)計(jì)之謬丘跌。
  • 冗長的子程序。很少會(huì)有超過一屏的子程序唁桩。
  • 長循環(huán)與深嵌套闭树。
  • 內(nèi)聚性太差的類或者模塊。如果某個(gè)模塊包含了許多彼此無關(guān)的方法荒澡,那么這個(gè)模塊本身的設(shè)計(jì)就是不合理的报辱。高內(nèi)聚,低耦合单山,能實(shí)現(xiàn)這兩點(diǎn)的人代碼設(shè)計(jì)水平一定很好捏肢。
  • 擁有太多參數(shù)的方法。
  • 一處變化饥侵,多處修改。如果外部有一個(gè)小小的改動(dòng)衣屏,或者產(chǎn)品加了一個(gè)新的需求躏升,你需要在多出進(jìn)行重復(fù)的修改,那么這個(gè)設(shè)計(jì)也是有問題的狼忱。
  • 流浪數(shù)據(jù)膨疏。把數(shù)據(jù)傳遞給某個(gè)子程序一睁,然后子程序?qū)?shù)據(jù)又傳遞給另一個(gè)子程序,這樣傳來傳去的數(shù)據(jù)被稱為流浪數(shù)據(jù)佃却。請確定是否有此必要者吁。
  • 命名問題。之前也說過變量命名饲帅,方法命名等技巧复凳,重構(gòu)的時(shí)候也需要注意。
  • 給難懂的代碼寫注釋灶泵。這里的注釋是辯解育八。某位大神曾說:不要為拙劣的代碼寫文檔——應(yīng)當(dāng)重寫代碼。
  • 全局變量赦邻。在修改別人的代碼時(shí)髓棋,你會(huì)切身體會(huì)到全局變量有多危險(xiǎn),應(yīng)當(dāng)避免使用全局變量惶洲。我還見過一種寫法按声,就是在一個(gè)對象里面包含了一些公共屬性,然后在這個(gè)類的各種成員方法里面會(huì)修改這些公共屬性恬吕,然后這些公共屬性又能暴露給其他對象使用签则,我覺得這樣的寫法會(huì)破壞封裝打破內(nèi)聚,是一種寫起來很爽但是維護(hù)起來相當(dāng)危險(xiǎn)的做法币呵。
  • 超前設(shè)計(jì)怀愧。程序中的代碼似乎是在將來的某個(gè)時(shí)候用的。書中認(rèn)為超前設(shè)計(jì)是一種畫蛇添足的做法余赢,增加了程序的復(fù)雜性并帶來了額外的工作量芯义。我覺得并不完全正確,一名優(yōu)秀的程序員應(yīng)該是充分了解業(yè)務(wù)的妻柒,雖然不能直接寫針對未來特定業(yè)務(wù)的代碼扛拨,但是可以對目前的某些方法進(jìn)行增強(qiáng),增強(qiáng)其擴(kuò)展性举塔。

以上關(guān)注點(diǎn)偏重于前端開發(fā)绑警,對于繼承,抽象這塊的話在JS中體現(xiàn)的并不強(qiáng)所以沒有關(guān)注央渣,大家也可以去翻翻書计盒。重構(gòu)的更多細(xì)節(jié),可以參考 Code Complete — 創(chuàng)建高質(zhì)量的代碼中的一些點(diǎn)來進(jìn)行芽丹。

最后再記錄一下重構(gòu)的幾個(gè)要點(diǎn):

  1. 重構(gòu)成功的關(guān)鍵在于程序員是否知道那些標(biāo)志著代碼需要重構(gòu)的點(diǎn)北启,并且程序員本身也能寫出高質(zhì)量的代碼;
  2. 要有安全重構(gòu)的策略。重構(gòu)有風(fēng)險(xiǎn)咕村,務(wù)必要小心场钉,同一時(shí)間只做一項(xiàng)重構(gòu),測試通過之后再進(jìn)行下一步會(huì)比較好懈涛。
  3. 改代碼是程序員始終要做的事情逛万,開發(fā)階段的重構(gòu)是風(fēng)險(xiǎn)最小,提升程序質(zhì)量的最佳時(shí)機(jī)批钠!

代碼調(diào)整策略和方法

很久以前宇植,計(jì)算機(jī)的性能有限,所以人們通常會(huì)書寫更利于節(jié)省資源的代碼价匠。后來硬件越來越強(qiáng)大当纱,程序員們意識(shí)到過于關(guān)注性能會(huì)損害程序的可讀性和可維護(hù)性,于是便開始轉(zhuǎn)移焦點(diǎn)踩窖。時(shí)至今日坡氯,代碼調(diào)整的最終目的是什么?是為了高效洋腮?還是可讀性和可維護(hù)性箫柳?還是兼具兩者?當(dāng)然兼具兩者最好啥供,然而有時(shí)候高效的代碼并不一定就是“更好”的代碼悯恍。

性能優(yōu)化誤區(qū)

  1. 代碼越少程序越快。現(xiàn)在應(yīng)該不會(huì)有人這樣想了吧伙狐。
  2. 特定的運(yùn)算可能比其他的快涮毫。在某些瀏覽器下面高效的寫法在另一個(gè)瀏覽器下面可能會(huì)很慢,所以在代碼調(diào)整的時(shí)候一定要小心效率最低的那個(gè)贷屎。比如DOM操作罢防。
  3. 應(yīng)當(dāng)隨時(shí)進(jìn)行優(yōu)化。當(dāng)程序沒有完成時(shí)唉侄,你很難知道瓶頸在哪里咒吐。而在一開始就想做到最優(yōu),往往會(huì)干擾自己對程序目標(biāo)的理解和判斷属划。二八法則同樣適用于軟件開發(fā):80%的性能恬叹,耗在了20%的代碼上面。
  4. 程序的運(yùn)行速度與其正確性同樣重要同眯。很顯然正確性更重要绽昼。

何時(shí)調(diào)整代碼

程序員應(yīng)當(dāng)使用高質(zhì)量的設(shè)計(jì)將程序編寫完成,使之易于維護(hù)须蜗,之后再去檢查系統(tǒng)性能硅确,然后分析瓶頸并對其優(yōu)化肿孵。

常見低效之源

  1. 輸入/輸出操作;
  2. 操作系統(tǒng)交換內(nèi)存頁面;
  3. 系統(tǒng)調(diào)用。調(diào)用子程序會(huì)涉及上下文切換;
  4. 解釋性語言疏魏。所以說,這是語言的先天缺陷;
  5. 錯(cuò)誤晤愧。沒有去掉調(diào)試信息大莫,忘了釋放內(nèi)存,超時(shí)等官份。

總結(jié)

性能只是軟件整體質(zhì)量的一個(gè)方面只厘,通常不是最重要的。只有當(dāng)性能影響到用戶體驗(yàn)時(shí)才需要進(jìn)行優(yōu)化舅巷。

相關(guān)文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羔味,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钠右,更是在濱河造成了極大的恐慌赋元,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件飒房,死亡現(xiàn)場離奇詭異搁凸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)狠毯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門护糖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嚼松,你說我怎么就攤上這事嫡良。” “怎么了献酗?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵寝受,是天一觀的道長。 經(jīng)常有香客問我凌摄,道長羡蛾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任锨亏,我火速辦了婚禮痴怨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘器予。我一直安慰自己浪藻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布乾翔。 她就那樣靜靜地躺著爱葵,像睡著了一般施戴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上萌丈,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天赞哗,我揣著相機(jī)與錄音,去河邊找鬼辆雾。 笑死肪笋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的度迂。 我是一名探鬼主播藤乙,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼惭墓!你這毒婦竟也來了坛梁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤腊凶,失蹤者是張志新(化名)和其女友劉穎划咐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吭狡,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡尖殃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了划煮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片送丰。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖弛秋,靈堂內(nèi)的尸體忽然破棺而出器躏,到底是詐尸還是另有隱情,我是刑警寧澤蟹略,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布登失,位于F島的核電站,受9級(jí)特大地震影響挖炬,放射性物質(zhì)發(fā)生泄漏揽浙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一意敛、第九天 我趴在偏房一處隱蔽的房頂上張望馅巷。 院中可真熱鬧,春花似錦草姻、人聲如沸钓猬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽敞曹。三九已至账月,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間澳迫,已是汗流浹背局齿。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留橄登,地道東北人项炼。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像示绊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子暂论,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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