《高效程序員的45個習(xí)慣》敏捷開發(fā)修煉之道——Subramaniam,Hunt

敏捷開發(fā)指的是在一個高度協(xié)作的環(huán)境中,不斷地使用反饋進(jìn)行自我調(diào)整和完善。

一般誤認(rèn)為,敏捷就是快,越快就是越敏捷,豈不知它本來要以 “l(fā)ightweight process”(輕量級過程)命名,只不過有些參會者不喜歡被看作是在舞臺上跳來跳去的輕量級拳手,所以才用了 “敏捷” 這個詞。敏捷不是目的,只是手段。只要某個手段適合某個場景,有助于提升質(zhì)量,提高交付能力,提高開發(fā)者水平……一切有利于團(tuán)隊(duì)建設(shè)、提高生產(chǎn)力的時間都應(yīng)該頻繁且持續(xù)做(比如回顧、測試、重構(gòu))然后日積月累就養(yǎng)成了習(xí)慣。習(xí)慣改變行為,行為決定命運(yùn)。

本書注重于培養(yǎng)軟件開發(fā)者的態(tài)度、原則、操守、價(jià)值觀。

只有明白了 “為什么做”,才能夠解決 “如何做” 的問題。為什么要做這件事情?它所帶來的好處是什么?如果不做它又會有哪些壞處?

迭代開發(fā),價(jià)值優(yōu)先

分解任務(wù),真實(shí)進(jìn)度

站立會議,交流暢通

用戶參與,調(diào)整方向

結(jié)對編程,代碼質(zhì)量

測試驅(qū)動,安全可靠

持續(xù)集成,盡早反饋

自動部署,一鍵安裝

定期回顧,持續(xù)改進(jìn)

不斷學(xué)習(xí),提高能力

第1章 敏捷——高效軟件開發(fā)之道

“不管路走了多遠(yuǎn),錯了就要重新返回。”——土耳其諺語

敏捷:只關(guān)注真正重要的事情,少關(guān)注那些占用大量時間而無甚裨益的不重要的事情。

敏捷開發(fā):一種把以人為本、團(tuán)隊(duì)合作、快速響應(yīng)變化和可工作的軟件作為宗旨的開發(fā)方法。

敏捷的重點(diǎn):貫穿項(xiàng)目的整個生命周期,持續(xù)開發(fā)、持續(xù)反饋。

開發(fā)要持續(xù)不斷,切勿時續(xù)時新 = Continuous development, not episodic

持續(xù)注入能量 = Inject energy

科普:

重構(gòu):在功能不變的情況下,重新設(shè)計(jì)部分代碼,改善代碼的質(zhì)量。

Wiki:Wiki 是一個網(wǎng)站,用戶通過瀏覽器,就可以編輯網(wǎng)頁內(nèi)容并創(chuàng)建鏈接到一個新的內(nèi)容頁面。Wiki 是一種很好的支持協(xié)作的工具,因?yàn)閳F(tuán)隊(duì)中的每一個人都可以根據(jù)需要動態(tài)地新增和重新組織網(wǎng)頁中的內(nèi)容,實(shí)現(xiàn)知識共享。

版本控制:項(xiàng)目開發(fā)中所有的產(chǎn)物(全部的源代碼、文檔、圖標(biāo)、構(gòu)建腳本等)都需要放入版本控制系統(tǒng)中,由版本控制系統(tǒng)來統(tǒng)一管理。

單元測試:用代碼來檢查代碼,這是開發(fā)者獲得反饋的主要來源。

自動構(gòu)建:不管是在自己的本地機(jī)器上實(shí)現(xiàn)構(gòu)建,還是為整個團(tuán)隊(duì)實(shí)現(xiàn)構(gòu)建,都是全自動化并可重復(fù)。因?yàn)檫@些構(gòu)建一直運(yùn)行,所以又稱為持續(xù)集成。和單元測試一樣,有大量的免費(fèi)開源產(chǎn)品和商業(yè)產(chǎn)品為你提供支持。

第 2 章 態(tài)度決定一切

“選定了要走的路,就是選定了它通往的目的地?!薄狧arry Emerson Fosidick(美國基督教現(xiàn)代主義神學(xué)家)

1.做事

2.欲速則不達(dá)

3.對事不對人

4.排除萬難,奮勇前進(jìn)

最高優(yōu)先級應(yīng)該是解決問題。為了解決或緩解這個問題,我能夠做些什么。專業(yè)的態(tài)度是著眼于項(xiàng)目和團(tuán)隊(duì)的積極結(jié)果,關(guān)注個人和團(tuán)隊(duì)的成長,圍繞最后的成功開展工作。集中注意力,你是為做事而工作的。

千里之堤,潰于蟻穴,大災(zāi)難是逐步演化來的。一次又一次的快速修復(fù),每一次都不探究問題的根源,久而久之就形成了一個危險(xiǎn)的沼澤地,最終會吞噬整個項(xiàng)目的生命。只要我們繼續(xù)進(jìn)行快速修復(fù),代碼的清晰度就不斷降低。一旦問題累積到一定程度,清晰的代碼就不復(fù)存在,只剩下一篇混沌。不要墜入快速的簡單修復(fù)之中。要投入時間和精力保持代碼的整潔、敞亮。拙劣的代碼工人會這樣不假思索地改完代碼,然后快速轉(zhuǎn)向下一個問題。優(yōu)秀的程序員會挖掘更深一層,盡力去理解為什么這里必須要加1,更重要的是,他會想明白會產(chǎn)生什么其他影響。

好的軟件開發(fā)作品和好的軟件設(shè)計(jì),都需要大量的創(chuàng)造力和洞察力。分享并融合各種不同的想法和觀點(diǎn),遠(yuǎn)遠(yuǎn)勝于單個想法為項(xiàng)目帶來的價(jià)值。在一個需要緊密合作的開發(fā)團(tuán)隊(duì)中,如果能稍加注意禮貌對待他人,將會有益于整個團(tuán)隊(duì)關(guān)注真正有價(jià)值的問題,而不是勾心斗角,誤入歧途。

指責(zé)不能修復(fù)bug = Blame doesn’t fix bugs

防微杜漸 = Beware of land mines

不要孤立地編碼 = Don’t code in isolation

使用單元測試 = Use unit tests

消極扼殺創(chuàng)新 = Negativity kills innovation

你不需要很出色才能起步,但是你必須起步才能變得很出色?!狶es Brown(全球領(lǐng)軍勵志演講家和作家)

絕妙的計(jì)劃會因?yàn)橛職獠蛔愣罱K失敗。你必須有勇氣向前沖鋒,做你認(rèn)為對的事情。

有效的特殊技術(shù):

- 設(shè)定最終期限。沒有最好的答案,只有更合適的方案。

- 逆向思維。先是積極地看到它的正面,然后在努力地從反面去認(rèn)識它。

- 設(shè)立仲裁人。仲裁人的責(zé)任就是確保每個人都有發(fā)言的機(jī)會,并維持會議的正常進(jìn)行。

- 支持已經(jīng)做出的決定。我們的目標(biāo)是讓項(xiàng)目成功滿足用戶需求。

第 3 章 學(xué)無止境

“即使你已經(jīng)在正確的軌道上,但如果只是停止不前,也仍然會被淘汰出局。”——Will Rogers(美國著名演員)

5、跟蹤變化

6、對團(tuán)隊(duì)投資

7、懂得丟棄

8、打破砂鍋問到底

9、把握開發(fā)節(jié)奏

敏捷的根本之一就是擁抱變化?!拔ㄓ凶兓怯篮愕??!薄绽死?/p>

你不需要精通所有的技術(shù),但需要清楚知道行業(yè)的動向,從而規(guī)劃你的項(xiàng)目和職業(yè)生涯。如何才能跟上技術(shù)變化的步伐?

- 迭代和增量式的學(xué)習(xí)。每天計(jì)劃用一段時間來學(xué)習(xí)新技術(shù)

- 了解最新行情。

- 參加本地的用戶組活動。

- 參加研討會議。

- 如饑似渴地閱讀。

午餐會議可以增進(jìn)每個人的知識和技能,并幫助大家聚集在一起進(jìn)行溝通交流。喚起人們對技術(shù)和技巧的激情,將會對項(xiàng)目大有裨益。

根深蒂固的習(xí)慣不可能輕易地就丟棄掉 = Expensive mental models aren’t discarded lightly.

不能只滿足于別人告訴你的表面現(xiàn)象。要不停地提問直到你明白問題的根源。

許多的敏捷技巧來源于時間盒——設(shè)定一個短時的期限,為任務(wù)設(shè)定不能延長的最終期限。你可以選擇放棄其他方面的任務(wù),但是最終期限是不變的。每個時間盒必須是短期的、有效的,并且要完成具體的目標(biāo)。當(dāng)你遇到艱難抉擇的時候,固定的時間期限會促使你做決定。

第 4 章 交付用戶想要的軟件

“沒有任何計(jì)劃在遇敵后還能繼續(xù)執(zhí)行。”——Helmuth von Moltke(德國陸軍元帥)

10、讓客戶做決定

11、讓設(shè)計(jì)指導(dǎo)而不是操作開發(fā)

12、合理地使用技術(shù)

13、保持可以發(fā)布

14、提早集成,頻繁集成

15、提早實(shí)現(xiàn)自動化部署

16、使用演示獲得頻繁反饋

17、使用短迭代,增量發(fā)布

18、固定的價(jià)格就意味著背叛承諾

開發(fā)者(及項(xiàng)目經(jīng)理)能做的一個最重要的決定就是:判斷哪些事自己決定不了的,應(yīng)該讓企業(yè)主做決定。開發(fā)者、經(jīng)理或者業(yè)務(wù)分析師不應(yīng)該做業(yè)務(wù)方面的決定。用業(yè)務(wù)負(fù)責(zé)人能夠理解的語言,向他們詳細(xì)解釋遇到的問題,并讓他們做決定。(決定什么不該決定 = Decide what you shouldn’t decide)

任何設(shè)計(jì)僅是一個起跑點(diǎn):它就像你的代碼一樣,在項(xiàng)目的生命周期中,會不停地進(jìn)一步發(fā)展和提煉。(戰(zhàn)略設(shè)計(jì)與戰(zhàn)術(shù)設(shè)計(jì) = Strategic versus tactical design)好的設(shè)計(jì)應(yīng)該是正確的,指引你向正確的方向前進(jìn),而不是精確的,它不應(yīng)該標(biāo)識具體的路線。也就是說,它描述的一切必須是正確的,不應(yīng)該設(shè)計(jì)不確定或者可能會發(fā)生變化的細(xì)節(jié)。它是目標(biāo),不是具體的處方。(設(shè)計(jì)滿足實(shí)現(xiàn)即可,不必過于詳細(xì) = Design should be only as detailed as needed to implement)好的設(shè)計(jì)十分重要。畫關(guān)鍵工作圖(例如,用UML)是必不可少的,因?yàn)橐褂妙惣捌浣换リP(guān)系來描繪系統(tǒng)是如何組織的。在做設(shè)計(jì)的時候,你需要花時間去思考(討論)各種不同選擇的缺陷和益處,以及如何做權(quán)衡。

根據(jù)需求選擇技術(shù)。首先決定什么是你需要的,接著為這些具體的問題評估使用技術(shù)。對任何要使用的技術(shù),多問一些挑剔的問題,并真實(shí)地作出回答。(盲目地為項(xiàng)目選擇技術(shù)框架,就好比是為了少交稅而生孩子 = Blindly picking a framework is like having kids to save taxes)不要開發(fā)你能下載到的東西 = Don’t build what you can download 雖然有時需要從最基礎(chǔ)開發(fā)所有你需要的東西,但那是相當(dāng)危險(xiǎn)和昂貴的。

任何時候只要你沒有準(zhǔn)備好,那就是敵人進(jìn)攻你的最佳時機(jī)。保持你的項(xiàng)目時刻可以發(fā)布,你的系統(tǒng)隨時可以編譯、運(yùn)行、測試并立即部署。(已提交的代碼應(yīng)該隨時可以行動 = Checked-in code is always ready for action)防止提交破壞系統(tǒng)的代碼工作流程:在本地運(yùn)行測試—>檢出最新的代碼—>提交代碼。

代碼集成是主要的風(fēng)險(xiǎn)來源。要想規(guī)避這個風(fēng)險(xiǎn),只有提早集成,持續(xù)而有規(guī)律地進(jìn)行集成。(絕不要做大爆炸式的集成 = Never accept big-bang integration)

一開始就進(jìn)行全面部署,而不是等到項(xiàng)目的后期。使用部署系統(tǒng)安裝你的應(yīng)用,在不同的機(jī)器上用不同的配置文件測試依賴的問題。系統(tǒng)的安裝或者部署應(yīng)該簡單、可靠及可重復(fù)。(質(zhì)量保證人員應(yīng)該測試部署過程 = QA should test deployment)

在開發(fā)的時候,要保持應(yīng)用可見(而且客戶心中也要了解)。每隔一周或者兩周,邀請所有的客戶,給他們演示最新完成的功能,積極獲得他們的反饋。演示是用來讓客戶提出反饋的,有助于駕馭項(xiàng)目的方向。(需求就像是流動著的油墨 = Requirements are as fluid as ink)

短迭代讓人感覺非常專注且具效率。你能看到一個實(shí)際并且確切的目標(biāo)。發(fā)布帶有最小卻可用功能塊的產(chǎn)品。每個增量開發(fā)中,使用 1~4 周左右迭代周期。(給我一份詳細(xì)的長期計(jì)劃,我就會給你一個注定完蛋的項(xiàng)目 = Show me a detailed long-term plan, and I’ll show you a project that’s doomed)

基于真實(shí)工作的評估。讓團(tuán)隊(duì)和客戶一起,真正地在當(dāng)前項(xiàng)目中工作,做具體實(shí)際的評估。由客戶控制他們要的功能和預(yù)算。(固定的價(jià)格就是保證要背叛承諾 = A fixed price guarantees a broken promise)

第 5 章 敏捷反饋

“一步行動,勝過千萬專家的意見?!薄狟ill Nye,The Science Guy科普節(jié)目主持人

19、守護(hù)天使

20、先用它再實(shí)現(xiàn)它

21、不同環(huán)境,就有不同問題

22、自動驗(yàn)收測試

23、度量真實(shí)的進(jìn)度

24、傾聽用戶的聲音

好的單元測試能夠?yàn)槟愕拇a問題提供及時的警報(bào)。如果沒有到位的單元測試,不要進(jìn)行任何設(shè)計(jì)和代碼修改。(編寫能產(chǎn)生反饋的代碼 = Coding feedback)

將 TDD 作為設(shè)計(jì)工具,它會為你帶來更簡單更有實(shí)效的設(shè)計(jì)(編碼之前,先寫測試 = Write tests before writing code)好的設(shè)計(jì)并不意味著需要更多的類 = Good design doesn’t mean more classes

使用持續(xù)集成工具,在每一種支持的平臺和環(huán)境中運(yùn)行單元測試。要積極地尋找問題,而不是等問題來找你。(使用自動化會節(jié)省時間 = Automate to save time)

不要用不恰當(dāng)?shù)亩攘縼砥垓_自己或者團(tuán)隊(duì)。要評估那些需要完成的待辦事項(xiàng)(backlog)(專注于你的方向 = Focus on where you’re going)

第 6 章 敏捷編碼

“任何一個笨蛋都能夠讓事情變得越來越笨重、越來越復(fù)雜、越來越極端。需要天才的指點(diǎn)以及許多的勇氣,才能讓事情向相反的方向發(fā)展?!薄狫ohn Dryden

25、代碼要清晰地表達(dá)意圖

26、用代碼溝通

27、動態(tài)評估取舍

28、增量式編程

29、保持簡單

30、編寫內(nèi)聚的代碼

31、告知,不要詢問

32、根據(jù)契約進(jìn)行替換

開發(fā)代碼時,應(yīng)該更注重可讀性,而不是只圖自己方便。例如,如果默認(rèn)參數(shù)或可選參數(shù)會影響代碼可讀性,使其更難以理解和調(diào)試,那最好明確地指明參數(shù),而不是在以后讓人覺得迷惑。

源代碼可以被讀懂,不是因?yàn)槠渲械淖⑨?,而?yīng)該是由于它本身優(yōu)雅而清晰——變量名運(yùn)用正確(i 表示循環(huán)索引變量。s 常被用來表示一個字符串)、空格使用得當(dāng)、邏輯分離清晰,以及表達(dá)式非常簡潔。使用細(xì)心選擇的、有意義的命名。用注釋描述代碼意圖和約束。代碼能夠自解釋,而不用依賴注釋,注釋不能替代優(yōu)秀的代碼。(不要用注釋來包裝你的代碼 = Don’t comment to cover up)

考慮性能、便利性、生產(chǎn)力、成本和上市時間。如果性能表現(xiàn)足夠了,就將注意力放在其他因素上。不要為了感覺上的性能提升或者設(shè)計(jì)的優(yōu)雅,而將設(shè)計(jì)復(fù)雜化。

增量式編程可以提煉并結(jié)構(gòu)化你的代碼。敏捷的方式在于持續(xù)做一些細(xì)小而有用的事情,而不是做一段長時間的編程和重構(gòu)。

優(yōu)雅是易于理解和辨識的,但是要想創(chuàng)造出來就困難得多了(簡單不是簡陋 = ?Simple is not simplistic)。

如果一個類的方法和屬性共同完成了一個功能(或者一系列緊密相關(guān)的功能),這個類就是內(nèi)聚的。要避免創(chuàng)建很大的類或組件,也不要創(chuàng)建無所不包的大雜燴類。

面向過程的代碼取得信息,然后做出決策。面向?qū)ο蟮拇a讓別的對象去做事情。作為某段代碼的調(diào)用者,開發(fā)人員絕對不應(yīng)該基于被調(diào)用對象的狀態(tài)來做出任何決策,更不能去改變該對象的狀態(tài)。這樣的邏輯應(yīng)該是被調(diào)用對象的責(zé)任,而不是你的。(將命令與查詢分離開來 = Keep commands separate from queries)

任何繼承后得到的派生類對象,必須可以替換任何被使用的基類對象,而且使用者不必知道任何差異。換句話說,某段代碼如果使用了基類中的方法,就必須能夠使用派生類的對象,并且自己不必進(jìn)行任何修改。

第 7 章 敏捷調(diào)試

“你也許會對木匠那毫無差錯的工作印象深刻。但我向你保證,事實(shí)不是這樣的。真正的高手只是知道如何亡羊補(bǔ)牢?!薄狫eff Miller,家具制造者、作家

33、記錄解決問題的日志

34、警告就是錯誤

35、對問題各個擊破

36、報(bào)告所有的異常

37、提供有用的錯誤信息

保留解決方案是修復(fù)問題過程的一部分,以后發(fā)生相同或類似問題時,就可以很快找到并使用了。每日日志daylog(不要在同一處跌倒兩次 = Don’t get burned twice)

簽入帶有警告的代碼,就跟簽入有錯誤或者沒有通過測試的代碼一樣,都是極差的做法。簽入構(gòu)建工具中的代碼不應(yīng)該產(chǎn)生任何警告信息。

識別復(fù)雜問題的第一步,是將它們分離出來。(用原型進(jìn)行分離 = Prototype to isolate)

處理或是向上傳播所有的異常。不要將它們壓制不管,就算是臨時這樣做也不行。在寫代碼時要估計(jì)到會產(chǎn)生的問題。

在開發(fā)過程中,如果定位和修復(fù)問題讓人被受挫則,就考慮使用更加積極主動的錯誤報(bào)告方式。展示有用的錯誤信息(錯誤類型:程序缺陷、環(huán)境問題、用戶錯誤。)。提供更易于查找錯誤細(xì)節(jié)的方式。發(fā)生問題時,要展示出盡量多的支持細(xì)節(jié),不過別讓用戶陷入其中。

第 8 章 敏捷寫作

“我不僅發(fā)揮了自己的全部能力,還將我所仰仗的人的能力發(fā)揮到極致。”——伍德羅·威爾遜,美國第 28 任總統(tǒng)

38、定期安排會面時間

39、架構(gòu)師必須寫代碼

40、實(shí)際代碼集成所有制

41、成為指導(dǎo)者

42、允許大家自己想辦法

43、準(zhǔn)備好后再共享代碼

44、做代碼復(fù)查

45、及時通報(bào)進(jìn)展與問題

溝通是項(xiàng)目成功的關(guān)鍵(昨天有什么收獲?今天計(jì)劃要做哪些工作?面臨著哪些障礙?)使用立會。立會可以讓團(tuán)隊(duì)達(dá)成共識。保證會議短小精悍不跑題。

優(yōu)秀的設(shè)計(jì)從積極的程序員那里開始演化。積極的編程可以帶來深入的理解。不要使用不愿意編程的架構(gòu)師。(不可能在 PowerPoint 幻燈片中進(jìn)行編程 = You can’t code in PowerPoint)沒有哪個決策做出之后就是板上釘釘?shù)摹?/p>

讓開發(fā)人員輪換完成系統(tǒng)不同領(lǐng)域中不同模塊的不同任務(wù)。

分享自己的知識很有趣——付出的同時便有收獲。還可以激勵別人獲得更好的成果,而且提升了整個團(tuán)隊(duì)的實(shí)力。(教學(xué)相長 = Knowledge grows when given)

給別人解決問題的機(jī)會。指給他們正確的方向,而不是直接提供解決方案。每個人都能從中學(xué)到不少東西。能欣賞自己并不接受的想法,表明你的頭腦足夠有學(xué)識?!獊喞锸慷嗟?/p>

絕對不要提交尚未完成的代碼。故意簽入編譯未通過或者沒有通過單元測試的代碼,對項(xiàng)目來說,應(yīng)該視作玩忽職守的犯罪行為。

對于提升代碼質(zhì)量和降低錯誤率來說,代碼復(fù)查是無價(jià)之寶。如果以正確的方式進(jìn)行,復(fù)查可以產(chǎn)生非常實(shí)用而高效的成果。要讓不同的開發(fā)人員在每個任務(wù)完成后復(fù)查代碼。

及時通報(bào)進(jìn)展與問題,有情況發(fā)生時,就不會讓別人感到突然,而且他們也很愿意了解目前的進(jìn)展?fàn)顩r。他們會知道何時應(yīng)提供幫助,而且你也獲得了他們的信任。

第 9 章 尾聲:走向敏捷

“一燈能除千年暗,一智能滅萬年愚?!薄勰?,中國禪宗第 6 代祖師

讀后感:習(xí)慣改變行為,行為決定命運(yùn)。養(yǎng)成好的習(xí)慣真的很重要,雖然這里寫的是高效程序員的45個習(xí)慣,但對于不是程序員的人來說,也是很有指導(dǎo)意義的。我們的人生也是需要不斷的通過復(fù)盤來回歸正道,一個大項(xiàng)目就像一個成人,有著精密的自我調(diào)試能力,如果一直積累一些不好的習(xí)慣,最后這個項(xiàng)目就會 bug 層出不窮,在解 bug 的過程中常常牽一發(fā)而動全身,解決了一個又出現(xiàn)了兩個,唯有養(yǎng)成好的習(xí)慣,不斷的迭代、回顧、總結(jié)才能走到最后。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,326評論 25 708
  • 先說項(xiàng)目開發(fā)過程中團(tuán)隊(duì)人員的分工協(xié)作。 一 人員安排 畢業(yè)至今的大部分項(xiàng)目都是獨(dú)立完成,雖然也有和其他同事協(xié)作的時...
    SnowflakeCloud閱讀 11,137評論 3 59
  • 何謂理性,理性就是知道自己錯了,有勇氣改正錯誤。別看就這點(diǎn)小事兒,我敢保證有很多人都做不到,例如孩子跟媽媽死性兒,...
    春曉育兒講堂閱讀 685評論 0 1
  • 三公子的《工作前5年,決定你一生的財(cái)富》。對于三公子其人,我想版友們都不會太陌生,是生活在我們周邊的一位理財(cái)達(dá)人,...
    慢兔君閱讀 357評論 0 3
  • 因?yàn)橐粋€夢,她交了心,賠了命,春曉夢回,她無法表達(dá),無力傾訴,只能獨(dú)自面對這排山倒海的思念與寂寞,是啊,僅僅是一個...
    年少清歡閱讀 325評論 0 0

友情鏈接更多精彩內(nèi)容