高效程序員的45個(gè)習(xí)慣_第1頁
高效程序員的45個(gè)習(xí)慣_第2頁
高效程序員的45個(gè)習(xí)慣_第3頁
高效程序員的45個(gè)習(xí)慣_第4頁
高效程序員的45個(gè)習(xí)慣_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、高效程序員的45個(gè)習(xí)慣內(nèi)容簡(jiǎn)介本書總結(jié)并生動(dòng)地闡述了成為高效的開發(fā)人員所需具備的45個(gè)習(xí)慣、思想觀念和方法,涵蓋了軟件開發(fā)進(jìn)程、編程和調(diào)試工作、開發(fā)者態(tài)度、項(xiàng)目和團(tuán)隊(duì)管理以及持續(xù)學(xué)習(xí)等幾個(gè)方面。本書適合所有程序員閱讀。本書簡(jiǎn)明實(shí)用、見解深刻,總結(jié)了高效程序員在開發(fā)過程中的45個(gè)個(gè)人習(xí)慣、思想觀念和方法,有助于開發(fā)人員在開發(fā)進(jìn)程、編碼工作、開發(fā)者態(tài)度、項(xiàng)目和團(tuán)隊(duì)管理,以及持續(xù)學(xué)習(xí)等5個(gè)方面積極修煉。通過學(xué)習(xí)這些內(nèi)容,養(yǎng)成這些好的習(xí)慣,你可以極大地提升自己的編程實(shí)力,更快速、更可靠地交付更高質(zhì)量的軟件,從而成為真正的高效程序員。目錄第1章敏捷高效軟件開發(fā)之道 1 第2章態(tài)度決定一切 10

2、 1做事 12 2欲速則不達(dá) 15 3對(duì)事不對(duì)人 18 4排除萬難,奮勇前進(jìn) 23 第3章學(xué)無止境 26 5跟蹤變化 28 6對(duì)團(tuán)隊(duì)投資 31 7懂得丟棄 34 8打破砂鍋問到底 37 9把握開發(fā)節(jié)奏 40 第4章交付用戶想要的軟件 43 10讓客戶做決定 45 11讓設(shè)計(jì)指導(dǎo)而不是操縱開發(fā) 48 12合理地使用技術(shù) 52 13保持可以發(fā)布 55 14提早集成,頻繁集成 58 15提早實(shí)現(xiàn)自動(dòng)化部署 61 16使用演

3、示獲得頻繁反饋 6417使用短迭代,增量發(fā)布 69 18固定的價(jià)格就意味著背叛承諾 73 第5章敏捷反饋 76 19守護(hù)天使 78 20先用它再實(shí)現(xiàn)它 82 21不同環(huán)境,就有不同問題 87 22自動(dòng)驗(yàn)收測(cè)試 90 23度量真實(shí)的進(jìn)度 93 24傾聽用戶的聲音 96 第6章敏捷編碼 98 25代碼要清晰地表達(dá)意圖 100 26用代碼溝通 105 27動(dòng)態(tài)評(píng)估取舍 110 28增量式編程 113 29保持簡(jiǎn)單 115 30編寫內(nèi)聚的代碼 117&#

4、160;31告知,不要詢問 121 32根據(jù)契約進(jìn)行替換 124 第7章敏捷調(diào)試 128 33記錄問題解決日志 129 34警告就是錯(cuò)誤 132 35對(duì)問題各個(gè)擊破 136 36報(bào)告所有的異常 139 37提供有用的錯(cuò)誤信息 141 第8章敏捷協(xié)作 146 38定期安排會(huì)面時(shí)間 148 39架構(gòu)師必須寫代碼 152 40實(shí)行代碼集體所有制 155 41成為指導(dǎo)者 157 42允許大家自己想辦法 160 43準(zhǔn)備好后再共享代碼 162 44做代碼復(fù)

5、查 165 45及時(shí)通報(bào)進(jìn)展與問題 168 第9章尾聲:走向敏捷 170 9.1只要一個(gè)新的習(xí)慣 170 9.2拯救瀕臨失敗的項(xiàng)目 171 9.3引入敏捷:管理者指南 172 9.4引入敏捷:程序員指南 174 9.5結(jié)束了嗎 175 附錄A資源 176 索引 182譯者序"武功者,包括內(nèi)功、外功、武術(shù)技擊術(shù)之總和。有形的動(dòng)作,如支撐格拒,姿式回環(huán),變化萬千,外部可見,授受較易,晨操夕練,不難熟練。而無形的內(nèi)功指內(nèi)部之靈惠素質(zhì),即識(shí)、膽、氣、勁、神是也,此乃與學(xué)練者整個(gè)內(nèi)在世界的學(xué)識(shí)水平密切相關(guān)

6、,是先天之慧根悟性與后天智能的總成,必需尋得秘籍方可煉成。"-摘自武林秘籍大全公元21世紀(jì),軟件業(yè)江湖動(dòng)蕩,人才輩出,各大門派林立,白道黑幫,都欲靠各自門派的武功稱霸武林。在那些外家功門派(傳統(tǒng)的瀑布開發(fā)方法、CMM、ISO和RUP等)和非正統(tǒng)教(中國(guó)式太極敏捷UDD等)當(dāng)?shù)乐H,一股新勢(shì)力正在崛起-以敏捷方法為總稱的一批內(nèi)家功門派。下面的歌訣是對(duì)內(nèi)家武功招數(shù)的概述:迭代開發(fā),價(jià)值優(yōu)先分解任務(wù),真實(shí)進(jìn)度站立會(huì)議,交流暢通用戶參與,調(diào)整方向結(jié)對(duì)編程,代碼質(zhì)量測(cè)試驅(qū)動(dòng),安全可靠持續(xù)集成,盡早反饋?zhàn)詣?dòng)部署,一鍵安裝定期回顧,持續(xù)改進(jìn)不斷學(xué)習(xí),提高能力上面的每種招式,都可尋得一本手冊(cè),介紹其

7、動(dòng)作要領(lǐng)和攻防章法。幾乎每個(gè)內(nèi)家功門派都有自己的拳法和套路。但,正所謂"練拳不練功,到老一場(chǎng)空"。學(xué)習(xí)招數(shù)和套路不難,難的是如何練就一身真功夫。內(nèi)家功,以練內(nèi)為主,內(nèi)外結(jié)合,以動(dòng)作引領(lǐng)內(nèi)氣,以內(nèi)氣催領(lǐng)動(dòng)作,通過后天的修煉來彌補(bǔ)先天的不足。本書是一本內(nèi)功手冊(cè)。它注重于培養(yǎng)軟件開發(fā)者的態(tài)度、原則、操守、價(jià)值觀,即識(shí)、膽、氣、勁、神是也。敏捷的實(shí)踐者Venkat Subramaniam和Andy Hunt攜手著下此書。望有志之士有緣得到此書,依法修習(xí),得其精要;由心知到身知,入筋、入骨、入髓,修煉得道。而后,匡扶正義,交付高質(zhì)量的軟件,為人類造福。安川2008年4月于北京推薦序一

8、僅僅還在幾年前,XP還被認(rèn)為是方法異教,F(xiàn)DD屬于黑客程序方法。如今,敏捷儼然已經(jīng)成為主流學(xué)說,敏捷方法成為人們學(xué)習(xí)和討論的熱點(diǎn)。敏捷方法的應(yīng)用也更加廣泛,以至于不少外包項(xiàng)目都要求采用某種敏捷方法。它不僅僅是小團(tuán)隊(duì)和小項(xiàng)目在使用,甚至連微軟都開始使用Scrum。敏捷已經(jīng)成為一種炙手可熱的新時(shí)尚。因?yàn)榛馃?,各種不同的說法就多起來;因?yàn)闀r(shí)尚,原本有些不認(rèn)同敏捷的人也開始追捧起來。人們反復(fù)地討論敏捷方法,涉及從哲學(xué)思想到實(shí)現(xiàn)細(xì)節(jié)的各個(gè)層面。人們不斷地推出各種不同版本的敏捷方法,甚至有些方法顯得如此矛盾、如此不同。同時(shí),一些誤解也一直在坊間流行。一般誤認(rèn)為敏捷就是快,越快就是越敏捷-字典上的名詞解釋是

9、其依據(jù)。豈不知它本來要以"lightweight processes"(輕量級(jí)過程)命名,只不過有些參會(huì)者不喜歡被看做是在拳臺(tái)上跳來跳去的輕量級(jí)拳手,所以才用了"敏捷"這個(gè)詞。還有其他一些誤解是,敏捷就是只寫代碼不寫文檔;敏捷需要重構(gòu)而無需設(shè)計(jì);敏捷迭代就是盡量做到最小,以至于一個(gè)小時(shí)就好幾次;敏捷需要天才的程序員才能應(yīng)用,其他人都會(huì)水土不服;如此這般。可以看到,市面上以敏捷為題目的圖書俯拾皆是,似乎軟件開發(fā)的書不加上敏捷這個(gè)詞就是落伍一樣。敏捷體系下存在多種方法,介紹每種方法的圖書就有一大堆。再加上每種方法采用不同的技術(shù),每本書采用不同的組織形式,存在

10、這么多書也不奇怪,就更不用提那些僅僅為了跟風(fēng)而敏捷的作品了。面對(duì)如此百花齊放、百家爭(zhēng)鳴的現(xiàn)象,你該從什么地方開始呢?有沒有一本圖書可以作為入門的第一讀物呢?這本書就可以勝任這樣的角色!這是一本很容易理解并掌握,不需要太多基礎(chǔ)就可以閱讀的書。不管你是開發(fā)人員,還是管理人員、財(cái)務(wù)等后勤人員、學(xué)生、編程愛好者,只要你對(duì)敏捷有興趣,就可以讀懂這本書。你不會(huì)被眾多的概念和曲折的邏輯所迷惑,不會(huì)被高難度技巧所困擾。這本書為你打開了了解和學(xué)習(xí)敏捷方法的一扇大門,并指出繼續(xù)前進(jìn)的道路。你會(huì)很悠閑自在地讀完這本小書,然后說:"原來敏捷就是這么一回事?。?quot;自由軟件顧問劉新生推薦序二我很喜歡本書

11、的中文書名-高效程序員的45個(gè)習(xí)慣,比直譯成"敏捷開發(fā)者實(shí)踐"含蓄多了。敏捷不是目的,只是手段。只要某個(gè)手段適合某個(gè)場(chǎng)景,有助于提升質(zhì)量,提高交付能力,提高開發(fā)者水平總而言之,有好處的事情,我們盡管做就是了,何必冠以敏捷之名?記得第一次讀本書還是兩年前。這時(shí)又細(xì)細(xì)讀來,越來越覺得"習(xí)慣"一詞比"實(shí)踐"更有味道。所謂"流水不腐,戶樞不蠹",廚房臟了就擦一下,總比滿墻都是油煙以后再去清理的代價(jià)小得多。有價(jià)值的東西-比如回顧、測(cè)試、重構(gòu),一切有利于團(tuán)隊(duì)建設(shè)、提高生產(chǎn)力的實(shí)踐都應(yīng)該頻繁且持續(xù)做,然后日積月累就養(yǎng)成了習(xí)慣。有

12、些習(xí)慣很容易養(yǎng)成,有些則很難。我們大都常常許愿,做計(jì)劃,比如要做一個(gè)至少100人同時(shí)在線的成熟應(yīng)用,參加義工活動(dòng),每周至少一篇博客然后在計(jì)劃落空的時(shí)候,用各種理由來安慰自己。李笑來老師在把時(shí)間當(dāng)作朋友一書中提到:"所有學(xué)習(xí)上的成功,都只靠?jī)杉拢翰呗院蛨?jiān)持,而堅(jiān)持本身就應(yīng)該是最重要的策略之一。"那么,為什么我們會(huì)在某些事情上堅(jiān)持不下去?或者換個(gè)角度來看,哪些事情是容易堅(jiān)持下去的?以前我是標(biāo)準(zhǔn)的宅男,CS、網(wǎng)絡(luò)小說、魔獸世界幾乎是休閑的全部,等到后來得了腰肌勞損,又得了頸椎病,這才痛定思痛,開始游泳鍛煉身體。每天游兩千米,一個(gè)月以后,游泳就成了習(xí)慣。再舉個(gè)例子,我老婆生完孩子

13、以后體型變化很大,立志想要減肥。為了堅(jiān)持下去,她把懷孕前的照片放在電腦桌面上,時(shí)時(shí)督促自己。后來,減肥也就變成了一種生活方式。從我的個(gè)人體驗(yàn)來看,難以堅(jiān)持下去的事情,基本都是因?yàn)闆]有迫切的欲望和激情。單說鍛煉身體,無論是為了減肥、祛病,還是塑形美體等,做這些事情至少都有明確的目的,這樣才能驅(qū)使著人們一直堅(jiān)持下去。沒有動(dòng)機(jī),沒有欲望,哪里來的毅力呢?那么,當(dāng)我們決定做一件事情的時(shí)候,首先就要多問問自己:為什么要做這件事情?它所帶來的好處是什么?如果不做它又會(huì)有哪些壞處?有了清晰的目的和思路后再去做事,遇到變化時(shí)就知道孰輕孰重,該怎么調(diào)整計(jì)劃,同時(shí)也不至于被重復(fù)和乏味消磨了一時(shí)的意氣。翻開本書之后

14、,你同樣也該對(duì)自己提問:"為什么要有自動(dòng)驗(yàn)收測(cè)試,有了足夠的單元測(cè)試是不是就能保證質(zhì)量了?""寫自動(dòng)驗(yàn)收測(cè)試有哪些成本,會(huì)帶來哪些收益?"只有明白了"為什么做",才能夠解決"如何做"的問題。本書的兩名譯者與我都是故交。錢安川是我的同事,是ThoughtWorks資深咨詢師,有豐富的敏捷實(shí)施經(jīng)驗(yàn)。鄭柯與我同是InfoQ中文站敏捷社區(qū)的編輯,一起翻譯過數(shù)十篇稿件。他翻譯的項(xiàng)目管理修煉之道也即將由圖靈公司出版。這次二人聯(lián)手的作品,定會(huì)給讀者以賞心悅目的閱讀體驗(yàn)。我有幸已經(jīng)從樣章中感受到了這一點(diǎn)。希望你能夠帶著問題,踏上愉

15、快的閱讀之旅。希望你能夠養(yǎng)成好習(xí)慣。【45個(gè)習(xí)慣簡(jiǎn)述】態(tài)度篇 1. 做實(shí)事不要抱怨,發(fā)牢騷,指責(zé)他人,找出問題所在,想辦法解決。對(duì)問題和錯(cuò)誤,要勇于承擔(dān)。2. 欲速則不達(dá)用小聰明、權(quán)宜之計(jì)解決問題,求快而不顧代碼質(zhì)量,會(huì)給項(xiàng)目留下要命的死角。3. 對(duì)事不對(duì)人就事論事,明智、真誠(chéng)、虛心地討論問題,提出創(chuàng)新方案。4. 排除萬難,奮勇前進(jìn)勇氣往往是克服困難的唯一方法。 學(xué)習(xí)篇5. 跟蹤變化新技術(shù)層出不窮并不可怕。堅(jiān)持學(xué)習(xí)新技術(shù),讀書,讀技術(shù)雜志,參加技術(shù)活動(dòng),與人交流。要多理解新詞背后的所以然,把握技術(shù)大趨勢(shì),將新技術(shù)用于產(chǎn)品開發(fā)要謹(jǐn)慎。6. 對(duì)團(tuán)隊(duì)投資打造學(xué)習(xí)型團(tuán)隊(duì),不斷提高兄

16、弟們的平均水平。7. 懂得丟棄老的套路和技術(shù),該丟,就得丟。不要固步自封。8. 打破砂鍋問到底不斷追問,真正搞懂問題的本質(zhì)。為什么?應(yīng)該成為你的口頭禪。9. 把握開發(fā)節(jié)奏控制好時(shí)間,養(yǎng)成好習(xí)慣,不要加班。 開發(fā)流程篇10. 讓客戶做決定讓用戶在現(xiàn)場(chǎng),傾聽他們的聲音,對(duì)業(yè)務(wù)最重要的決策應(yīng)該讓他們說了算。11. 讓設(shè)計(jì)指導(dǎo)而不是操縱開發(fā)設(shè)計(jì)是前進(jìn)的地圖,它指引的是方向,而不是目的本身。設(shè)計(jì)的詳略程度應(yīng)該適當(dāng)。12. 合理地使用技術(shù)根據(jù)需要而不是其他因素選擇技術(shù)。對(duì)各種技術(shù)方案進(jìn)行嚴(yán)格地追問,真誠(chéng)面對(duì)各種問題。13. 讓應(yīng)用隨時(shí)都可以發(fā)布通過善用持續(xù)集成和版本管理,你應(yīng)該隨時(shí)都能夠編譯、運(yùn)

17、行甚至部署應(yīng)用。14. 提早集成,頻繁集成集成有風(fēng)險(xiǎn),要盡早盡量多地集成。15. 提早實(shí)現(xiàn)自動(dòng)化部署16. 使用演示獲得頻繁反饋17. 使用短迭代,增量發(fā)布18. 固定價(jià)格就意味著背叛承諾估算應(yīng)該基于實(shí)際的工作不斷變化。 用戶篇19. 守護(hù)天使自動(dòng)化單元測(cè)試是你的守護(hù)天使。20. 先用它再實(shí)現(xiàn)它測(cè)試驅(qū)動(dòng)開發(fā)其實(shí)是一種設(shè)計(jì)工具。21. 不同環(huán)境,就有不同問題要重視多平臺(tái)問題。22. 自動(dòng)驗(yàn)收測(cè)試23. 度量真實(shí)的進(jìn)度在工作量估算上,不要自欺欺人。24. 傾聽用戶的聲音每一聲抱怨都隱藏著寶貴的真理。 編程篇25. 代碼要清晰地表達(dá)意圖(免費(fèi)樣章鏈接)代碼是給人讀的,不要耍小聰明

18、。26. 用代碼溝通注釋的藝術(shù)。27. 動(dòng)態(tài)地進(jìn)行取舍(免費(fèi)樣章鏈接)記住,沒有最佳解決方案。各種目標(biāo)不可能面面俱到,關(guān)注對(duì)用戶重要的需求。28. 增量式編程寫一點(diǎn)代碼就構(gòu)建、測(cè)試、重構(gòu)、休息。讓代碼干凈利落。29. 盡量簡(jiǎn)單寧簡(jiǎn)勿繁。如果沒有充足的理由,就不要使用什么模式、原則和特別的技術(shù)。30. 編寫內(nèi)聚的代碼類和組件應(yīng)該足夠小,任務(wù)單一。31. 告知,不要詢問多用消息傳遞,少用函數(shù)調(diào)用。32. 根據(jù)契約進(jìn)行替換委托往往優(yōu)于繼承。 調(diào)試篇33. 記錄問題解決日志(免費(fèi)樣章鏈接)不要在同一地方摔倒兩次。錯(cuò)誤是最寶貴的財(cái)富。34. 警告就是錯(cuò)誤忽視編譯器的警告可能鑄成大錯(cuò)。35. 對(duì)

19、問題各個(gè)擊破(免費(fèi)樣章鏈接)分而治之是計(jì)算機(jī)科學(xué)中最重要的思想之一。但是,要從設(shè)計(jì)和原型階段就考慮各部分應(yīng)該能夠很好地分離。36. 報(bào)告所有的異常37. 提供有用的錯(cuò)誤信息(免費(fèi)樣章鏈接)稍微多花一點(diǎn)心思,出錯(cuò)的時(shí)候,將給你帶來極大便利。 團(tuán)隊(duì)協(xié)作篇38. 定期安排會(huì)面時(shí)間常開會(huì),開短會(huì)。39. 架構(gòu)師必須寫代碼(免費(fèi)樣章鏈接)不寫代碼的架構(gòu)師不是好架構(gòu)師。好的設(shè)計(jì)都來自實(shí)際編程。編程可以帶來深入的理解。40. 實(shí)行代碼集體所有制讓開發(fā)人員在系統(tǒng)不同區(qū)域中不同的模塊和任務(wù)之間輪崗。41. 成為指導(dǎo)者教學(xué)相長(zhǎng)。分享能提高團(tuán)隊(duì)的總體能力。42. 讓大家自己想辦法(免費(fèi)樣章鏈接)指引方向,

20、而不是直接提供解決方案。讓每個(gè)人都有機(jī)會(huì)在干中學(xué)習(xí)。43. 準(zhǔn)備好后再共享代碼不要提交無法編譯或者沒有通過單元測(cè)試的代碼!44. 做代碼復(fù)查復(fù)查對(duì)提高代碼質(zhì)量、減少錯(cuò)誤極為重要。45. 及時(shí)通報(bào)進(jìn)展與問題(免費(fèi)樣章鏈接)主動(dòng)通報(bào),不要讓別人來問你?!?5個(gè)習(xí)慣詳述】第1章敏捷高效軟件開發(fā)之道第2章態(tài)度決定一切1做事2快速修復(fù)變成了快速流沙3對(duì)事不對(duì)人4排除萬難,奮勇前進(jìn)第3章學(xué)無止境5跟蹤變化6對(duì)團(tuán)隊(duì)投資7懂得丟棄8打破砂鍋問到底9把握開發(fā)節(jié)奏第4章交付用戶想要的軟件10讓客戶做決定11讓設(shè)計(jì)指導(dǎo)開發(fā),而不是操縱開發(fā)12合理地使用技術(shù)13保持可以發(fā)布14提早集成,頻繁集成15提早實(shí)現(xiàn)自動(dòng)化部署

21、16頻繁地演示獲得用戶反饋17使用短迭代,增量發(fā)布18固定的價(jià)格就意味著背叛承諾第5章敏捷反饋19守護(hù)天使20先用它再實(shí)現(xiàn)它21不同環(huán)境,就有不同問題22自動(dòng)驗(yàn)收測(cè)試23度量真實(shí)的進(jìn)度24傾聽用戶的聲音第6章敏捷編碼25習(xí)慣25:代碼要清晰地表達(dá)意圖  “可以工作而且易于理解的代碼挺好,但是讓人覺得聰明更加重要。別人給你錢是因?yàn)槟隳X子好使,讓我們看看你到底有多聰明?!?#160; Hoare 談軟件設(shè)計(jì)C.A.R. Hoare設(shè)計(jì)軟件有兩種方式。一種是設(shè)計(jì)得盡量簡(jiǎn)單,并且明顯沒有缺陷。另一種方式是設(shè)計(jì)得盡量復(fù)雜,并且沒有明顯的缺陷。我們大概都見過不少難以理解和維護(hù)的代碼,而且(最壞的

22、是)還有錯(cuò)誤。當(dāng)開發(fā)人員們像一群旁觀者見到UFO一樣圍在代碼四周,同樣也感到恐懼、困惑與無助時(shí),這個(gè)代碼的質(zhì)量就可想而知了。如果沒有人理解一段代碼的工作方式,那這段代碼還有什么用呢?開發(fā)代碼時(shí),應(yīng)該更注重可讀性,而不是只圖自己方便。代碼被閱讀的次數(shù)要遠(yuǎn)遠(yuǎn)超過被編寫的次數(shù),所以在編寫的時(shí)候值得花點(diǎn)功夫讓它讀起來更加簡(jiǎn)單。實(shí)際上,從衡量標(biāo)準(zhǔn)上來看,代碼清晰程度的優(yōu)先級(jí)應(yīng)該排在執(zhí)行效率之前。例如,如果默認(rèn)參數(shù)或可選參數(shù)會(huì)影響代碼可讀性,使其更難以理解和調(diào)試,那最好明確地指明參數(shù),而不是在以后讓人覺得迷惑。在改動(dòng)代碼以修復(fù)bug或者添加新功能時(shí),應(yīng)該有條不紊地進(jìn)行。首先,應(yīng)該理解代碼做了什么,它是如何

23、做的。接下來,搞清楚將要改變哪些部分,然后著手修改并進(jìn)行測(cè)試。作為第1步的理解代碼,往往是最難的。如果別人給你的代碼很容易理解,接下來的工作就省心多了。要敬重這個(gè)黃金法則,你欠他們一份情,因此也要讓你自己的代碼簡(jiǎn)單、便于閱讀。明白地告訴閱讀程序的人,代碼都做了什么,這是讓其便于理解的一種方式。讓我們看一些例子。coffeeShop.PlaceOrder(2);通過閱讀上面的代碼,可以大致明白這是要在咖啡店中下一個(gè)訂單。但是,2到底是什么意思?是意味著要兩杯咖啡?要再加兩次?還是杯子的大???要想搞清楚,唯一的方式就是去看方法定義或者文檔,因?yàn)檫@段代碼沒有做到清晰易懂。所以我們不妨添加一些注釋。c

24、offeeShop.PlaceOrder(2 /* large cup */); 現(xiàn)在看起來好一點(diǎn)了,但是注釋有時(shí)候是用來對(duì)寫得很差的代碼進(jìn)行補(bǔ)償?shù)模ㄒ姷?05 頁中習(xí)慣26:用代碼溝通)。Java 5與.NET中有枚舉值的概念,我們不妨使用一下。使用C#,我們可以定義一個(gè)名為CoffeeCupSize的枚舉,如下所示。public enum CoffeeCupSize  Small,  Medium,  Large        接下來就可以用它來下單要咖啡了。  

25、;      coffeeShop.PlaceOrder(CoffeeCupSize.Largxe);這段代碼就很明白了,我們是要一個(gè)大杯的咖啡。作為一個(gè)開發(fā)者,應(yīng)該時(shí)常提醒自己是否有辦法讓寫出的代碼更容易理解。下面是另一個(gè)例子。Line 1   public int compute(int val)     -       -     int result = val << 1;  

26、   -    /. more code .     5     return result;     -  第3行中的位移操作符是用來干什么的?如果善于進(jìn)行位運(yùn)算,或者熟悉邏輯設(shè)計(jì)或匯編編程,就會(huì)明白我們所做的只是把val的值乘以2。       PIE原則       所寫的代碼必須明確表達(dá)你的意圖,而且必須富有表

27、現(xiàn)力。這樣可以讓代碼更易于被別人閱讀和理解。代碼不讓人迷惑,也就減少了發(fā)生潛在錯(cuò)誤的可能。代碼要清晰地表達(dá)意圖。但對(duì)沒有類似背景的人們來說,又會(huì)如何他們能明白嗎?也許團(tuán)隊(duì)中有一些剛剛轉(zhuǎn)行做開發(fā)、沒有太多經(jīng)驗(yàn)的成員。他們會(huì)撓頭不已,直到把頭發(fā)抓下來。代碼執(zhí)行效率也許很高,但是缺少明確的意圖和表現(xiàn)力。用位移做乘法,是在對(duì)代碼進(jìn)行不必要且危險(xiǎn)的性能優(yōu)化。result=val*2看起來更加清晰,也可以達(dá)到目的,而且對(duì)于某種給定的編譯器來說,可能效率更高(積習(xí)難改,見第34頁的習(xí)慣7)。不要表現(xiàn)得好像很聰明似的,要遵循PIE原則:代碼要清晰地表達(dá)意圖。要是違反了PIE原則,造成的問題可就不只是代碼可讀性

28、那么簡(jiǎn)單了它會(huì)影響到代碼的正確性。下列代碼是一個(gè)C#方法,試圖同步對(duì)CoffeeMaker中MakeCoffee()方法進(jìn)行調(diào)用。Public void MakeCoffee()    lock(this)          / . operation    這個(gè)方法的作者想設(shè)置一個(gè)臨界區(qū)(critical section)任何時(shí)候最多只能有一個(gè)線程來執(zhí)行operation中的代碼。要達(dá)到這個(gè)目的,作者在CoffeeMaker實(shí)例中聲明了一個(gè)鎖。一個(gè)線程只有獲得這個(gè)鎖,才能執(zhí)行這個(gè)方法

29、。(在Java中,會(huì)使用synchronized而不是lock,不過想法是一樣的。)對(duì)于Java或.NET程序員來說,這樣寫順理成章,但是其中有兩個(gè)小問題。首先,鎖的使用影響范圍過大;其次,對(duì)一個(gè)全局可見的對(duì)象使用了鎖。我們進(jìn)一步來看看這兩個(gè)問題。假設(shè)Coffeemaker同時(shí)可以提供熱水,因?yàn)橛行┤讼M缟夏軌蛳碛靡稽c(diǎn)伯爵紅茶。我想同步GetWater()方法,因此調(diào)用其中的lock(this)。這會(huì)同步任何在CoffeeMaker上使用lock 的代碼,也就意味著不能同時(shí)制作咖啡以及獲取熱水。這是開發(fā)者原本的意圖嗎?還是鎖的影響范圍太大了?通過閱讀代碼并不能明白這一點(diǎn),使用代碼的人也就迷惑

30、不已了。同時(shí),MakeCoffee()方法的實(shí)現(xiàn)在CoffeeMaker對(duì)象上聲明了一個(gè)鎖,而應(yīng)用的其他部分都可以訪問CoffeeMaker對(duì)象。如果在一個(gè)線程中鎖定了CoffeeMaker對(duì)象實(shí)例,然后在另外一個(gè)線程中調(diào)用那個(gè)實(shí)例之上的MakeCoffee()方法呢?最好的狀況也會(huì)執(zhí)行效率很差,最壞的狀況會(huì)帶來死鎖。讓我們?cè)谶@段代碼上應(yīng)用PIE原則,通過修改讓它變得更加明確吧。我們不希望同時(shí)有兩個(gè)或更多的線程來執(zhí)行MakeCoffee()方法。那為什么不能為這個(gè)目的創(chuàng)建一個(gè)對(duì)象并鎖定它呢?Private object makeCoffeeLock = new Object();Public

31、void MakeCoffee()    lock (makeCoffeeLock)          / . operation    這段代碼解決了上面的兩個(gè)問題我們通過指定一個(gè)外部對(duì)象來進(jìn)行同步操作,而且更加明確地表達(dá)了意圖。在編寫代碼時(shí),應(yīng)該使用語言特性來提升表現(xiàn)力。使用方法名來傳達(dá)意向,對(duì)方法參數(shù)的命名要幫助讀者理解背后的想法。異常傳達(dá)的信息是哪些可能會(huì)出問題,以及如何進(jìn)行防御式編程,要正確地使用和命名異常。好的編碼規(guī)范可以讓代碼變得易于理解,同時(shí)減少不必要的注釋和文檔。要編寫清晰的而

32、不是討巧的代碼向代碼閱讀者明確表明你的意圖。可讀性差的代碼一點(diǎn)都不聰明。  切身感受應(yīng)該讓自己或團(tuán)隊(duì)的其他任何人,可以讀懂自己一年前寫的代碼,而且只讀一遍就知道它的運(yùn)行機(jī)制。平衡的藝術(shù)· 現(xiàn)在對(duì)你顯而易見的事情,對(duì)別人可能并不顯然,對(duì)于一年以后的你來說,也不一定顯然。不妨將代碼視作不知道會(huì)在未來何時(shí)打開的一個(gè)時(shí)間膠囊。· 不要明日復(fù)明日。如果現(xiàn)在不做的話,以后你也不會(huì)做的。· 有意圖的編程并不是意味著創(chuàng)建更多的類或者類型。這不是進(jìn)行過分抽象的理由。使用符合當(dāng)時(shí)情形的耦合。例如,通過散列表進(jìn)行松耦合,這種方式適用于在實(shí)際狀況中就是松耦合的組件。不要使用散列

33、表存儲(chǔ)緊密耦合的組件,因?yàn)檫@樣沒有明確表示出你的意圖。對(duì)星巴克的粉絲來說,這是指venti。沒錯(cuò),那不是一塊禿頂,而是一個(gè)編程機(jī)器的太陽能電池板。 26用代碼溝通27習(xí)慣27:動(dòng)態(tài)評(píng)估取舍“性能、生產(chǎn)力、優(yōu)雅、成本以及上市時(shí)間,在軟件開發(fā)過程中都是至關(guān)重要的因素。每一項(xiàng)都必須達(dá)到最理想狀態(tài)?!笨赡茉?jīng)身處這樣的團(tuán)隊(duì):管理層和客戶將很大一部分注意力都放在應(yīng)用的界面展示上。也有這樣的團(tuán)隊(duì),其客戶認(rèn)為性能表現(xiàn)非常重要。在團(tuán)隊(duì)中,你可能會(huì)發(fā)現(xiàn),有這樣一個(gè)開發(fā)主管或者架構(gòu)師,他會(huì)強(qiáng)調(diào)遵守“正確”的范式比其他任何事情都重要。對(duì)任何單個(gè)因素如此獨(dú)斷地強(qiáng)調(diào),而不考慮它是否是項(xiàng)目成功的必要因素,必然導(dǎo)

34、致災(zāi)難的發(fā)生。強(qiáng)調(diào)性能的重要性情有可原,因?yàn)閻毫拥男阅鼙憩F(xiàn)會(huì)讓一個(gè)應(yīng)用在市場(chǎng)上鎩羽而歸。然而,如果應(yīng)用的性能已經(jīng)足夠好了,還有必要繼續(xù)投入精力讓其運(yùn)行得更快一點(diǎn)嗎?大概不用了吧。一個(gè)應(yīng)用還有很多其他方面的因素同樣重要。與其花費(fèi)時(shí)間去提升千分之一的性能表現(xiàn),也許減少開發(fā)投入,降低成本,并盡快讓應(yīng)用程序上市銷售更有價(jià)值。舉例來說,考慮一個(gè)必須要與遠(yuǎn)程Windows服務(wù)器進(jìn)行通訊的.NET Windows應(yīng)用程序??梢赃x擇使用.NET Remoting 技術(shù)或Web Services來實(shí)現(xiàn)這個(gè)功能?,F(xiàn)在,針對(duì)使用Web Services的提議,有些開發(fā)者會(huì)說:“我們要在Windows之間進(jìn)行通信,通

35、常此類情況下,推薦使用.NET Remoting。而且,Web Services很慢,我們會(huì)遇到性能問題?!编?,一般來說確實(shí)是這樣。然而,在這個(gè)例子中,使用Web Services很容易開發(fā)。對(duì)Web Services的性能測(cè)試表明XML文檔很小,并且相對(duì)應(yīng)用程序自己的響應(yīng)時(shí)間來講,花在創(chuàng)建和解析XML上的時(shí)間幾乎可以忽略不計(jì)。使用Web Services不但可以在短期內(nèi)節(jié)省開發(fā)時(shí)間,且在此后團(tuán)隊(duì)被迫使用第三方提供的服務(wù)時(shí),Web Services也是個(gè)明智的選擇。Andy 說。過猶不及我曾經(jīng)遇到這樣一個(gè)客戶,他們堅(jiān)信可配置性的重要性,致使他們的應(yīng)用有大概10 000個(gè)可配置變量。新增代碼變得

36、異常艱難,因?yàn)橐ㄙM(fèi)大量時(shí)間來維護(hù)配置應(yīng)用程序和數(shù)據(jù)庫。但是他們堅(jiān)信需要這種程度的靈活性,因?yàn)槊總€(gè)客戶都有不同的需求,需要不同的設(shè)置??蓪?shí)際上,他們只有19個(gè)客戶,而且預(yù)計(jì)將來也不會(huì)超過50個(gè)。他們并沒有很好地去權(quán)衡。考慮這樣一個(gè)應(yīng)用,從數(shù)據(jù)庫中讀取數(shù)據(jù),并以表格方式顯示。你可以使用一種優(yōu)雅的、面向?qū)ο蟮姆绞?,從?shù)據(jù)庫中取數(shù)據(jù),創(chuàng)建對(duì)象,再將它們返回給UI層。在UI層中,你再從對(duì)象中拆分出數(shù)據(jù),并組織為表格方式顯示。除了看起來優(yōu)雅之外,這樣做還有什么好處嗎?也許你只需要讓數(shù)據(jù)層返回一個(gè)dataset或數(shù)據(jù)集合,然后用表格顯示這些數(shù)據(jù)即可。這樣還可以避免對(duì)象創(chuàng)建和銷毀所耗費(fèi)的資源。如果需要的只是

37、數(shù)據(jù)展示,為什么要?jiǎng)?chuàng)建對(duì)象去自找麻煩呢?不按書上說的OO方式來做,可以減少投入,同時(shí)獲得性能上的提升。當(dāng)然,這種方式有很多缺點(diǎn),但問題的關(guān)鍵是要多長(zhǎng)個(gè)心眼兒 ,而不是總按照習(xí)慣的思路去解決問題??偠灾?,要想讓應(yīng)用成功,降低開發(fā)成本與縮短上市時(shí)間,二者的影響同樣重要。由于計(jì)算機(jī)硬件價(jià)格日益便宜,處理速度日益加快,所以可在硬件上多投入以換取性能的提升,并將節(jié)省下來的時(shí)間放在應(yīng)用的其他方面。當(dāng)然,這也不完全對(duì)。如果硬件需求非常龐大,需要一個(gè)巨大的計(jì)算機(jī)網(wǎng)格以及眾多的支持人員才能維持其正常運(yùn)轉(zhuǎn)(比如類似Google那樣的需求),那么考慮就要向天平的另一端傾斜了。但是誰來最終判定性能表現(xiàn)已經(jīng)足夠好,或

38、是應(yīng)用的展現(xiàn)已經(jīng)足夠“炫”了呢?客戶或是利益相關(guān)者必須進(jìn)行評(píng)估,并做出相關(guān)決定(見第45頁中習(xí)慣10)。如果團(tuán)隊(duì)認(rèn)為性能上還有提升的空間,或者覺得可以讓某些界面看起來更吸引人,那么就去咨詢一下利益相關(guān)者,讓他們決定應(yīng)將重點(diǎn)放在哪里。沒有適宜所有狀況的最佳解決方案。你必須對(duì)手上的問題進(jìn)行評(píng)估,并選出最合適的解決方案。每個(gè)設(shè)計(jì)都是針對(duì)特定問題的只有明確地進(jìn)行評(píng)估和權(quán)衡,才能得出更好的解決方案。沒有最佳解決方案(No best solution)動(dòng)態(tài)評(píng)估權(quán)衡考慮性能、便利性、生產(chǎn)力、成本和上市時(shí)間。如果性能表現(xiàn)足夠了,就將注意力放在其他因素上。不要為了感覺上的性能提升或者設(shè)計(jì)的優(yōu)雅,而將設(shè)計(jì)復(fù)雜化。

39、 切身感受即使不能面面俱到,你也應(yīng)該覺得已經(jīng)得到了最重要的東西客戶認(rèn)為有價(jià)值的特性。平衡的藝術(shù)· 如果現(xiàn)在投入額外的資源和精力,是為了將來可能得到的好處,要確認(rèn)投入一定要得到回報(bào)(大部分情況下,是不會(huì)有回報(bào)的)。真正的高性能系統(tǒng),從一開始設(shè)計(jì)時(shí)就在向這個(gè)方向努力。· 過早的優(yōu)化是萬惡之源。· 過去用過的解決方案對(duì)當(dāng)前的問題可能適用,也可能不適用。不要事先預(yù)設(shè)結(jié)論,先看看現(xiàn)在是什么狀況。 28增量式編程29保持簡(jiǎn)單30編寫內(nèi)聚的代碼31告知,不要詢問32根據(jù)契約進(jìn)行替換第7章 敏捷調(diào)試你也許會(huì)對(duì)木匠那毫無差錯(cuò)的工作印象深刻。但我向你保證,事實(shí)不是

40、這樣的。真正的高手只是知道如何亡羊補(bǔ)牢。-Jeff Miller,家具制造者、作家即使是運(yùn)作得最好的敏捷項(xiàng)目,也會(huì)發(fā)生錯(cuò)誤。bug、錯(cuò)誤、缺陷-不管被稱作什么,它們總會(huì)發(fā)生。在調(diào)試時(shí)面對(duì)的真正問題,是無法用固定的時(shí)間來限制??梢砸?guī)定設(shè)計(jì)會(huì)議的持續(xù)時(shí)間,并在時(shí)間截止時(shí)決定采用最佳的方案。但是調(diào)試所耗費(fèi)的時(shí)間,可能是一個(gè)小時(shí)、一天,甚至一周過去了,還是沒有辦法找到并解決問題。對(duì)于一個(gè)項(xiàng)目來說,這種沒有準(zhǔn)確把握的時(shí)間消耗是不可接受的。不過,我們可以使用一些輔助技術(shù),涵蓋的范圍包括:保留以前的問題解決方案,以及提供發(fā)生問題時(shí)的更多有用細(xì)節(jié)。要想更加有效地重用你的知識(shí)和努力,記錄問題解決日志是很有用的,

41、我們會(huì)在下一頁看到如何具體操作。當(dāng)編譯器警告有問題的時(shí)候,要假定警告就是錯(cuò)誤,并且馬上把它們解決掉(第132頁)。想在一個(gè)完整的系統(tǒng)中跟蹤問題非常困難-甚至是不可能的。如果可以對(duì)問題各個(gè)擊破,正如我們?cè)诘?36頁中看到的那樣,就更容易找到問題了。不同于某些欲蓋彌彰的行為,應(yīng)該報(bào)告所有的異常,如第139頁所述。最后,在報(bào)告某些事情出錯(cuò)之時(shí),必須要考慮用戶的感受,并且提供有用的錯(cuò)誤信息。我們會(huì)在第141頁看到這是為什么。33習(xí)慣33:記錄問題解決日志“在開發(fā)過程中是不是經(jīng)常遇到似曾相識(shí)的問題?這沒關(guān)系。以前解決過的問題,現(xiàn)在還是可以解決掉的?!泵鎸?duì)問題(并解決它們)是開發(fā)人員的一種生活方式。當(dāng)問題

42、發(fā)生時(shí),我們希望趕緊把它解決掉。如果一個(gè)熟悉的問題再次發(fā)生,我們會(huì)希望記起第一次是如何解決的,而且希望下次能夠更快地把它搞定。然而,有時(shí)一個(gè)問題看起來跟以前遇到的完全一樣,但是我們卻不記得是如何修復(fù)的了。這種狀況時(shí)常發(fā)生。不能通過Web搜索獲得答案嗎?畢竟互聯(lián)網(wǎng)已經(jīng)成長(zhǎng)為如此令人難以置信的信息來源,我們也應(yīng)該好好加以利用。從Web上尋找答案當(dāng)然勝過僅靠個(gè)人努力解決問題??蛇@是非常耗費(fèi)時(shí)間的過程。有時(shí)可以找到需要的答案,有時(shí)除了找到一大堆意見和建議之外,發(fā)現(xiàn)不了實(shí)質(zhì)性的解決方案??吹接卸嗌匍_發(fā)人員遇到同樣的問題,也許會(huì)感覺不錯(cuò),但我們需要的是一個(gè)解決辦法。要想得到更好的效果,不妨維護(hù)一個(gè)保存曾遇

43、到的問題以及對(duì)應(yīng)解決方案的日志。這樣,當(dāng)問題發(fā)生時(shí),就不必說:“嘿,我曾碰到過這個(gè)問題,但是不記得是怎么解決的了。”可以快速搜索以前用過的方法。工程師們已經(jīng)使用這種方式很多年了,他們稱之為每日日志(daylog)。不要在同一處跌倒兩次                     Don't get burned twice  可以選擇符合需求的任何格式。下面這些條目可能會(huì)用得上。&#

44、183; 問題發(fā)生日期。· 問題簡(jiǎn)述。· 解決方案詳細(xì)描述。· 引用文章或網(wǎng)址,以提供更多細(xì)節(jié)或相關(guān)信息。· 任何代碼片段、設(shè)置或?qū)υ捒虻慕仄?,只要它們是解決方案的一部分,或者可以幫助更深入地理解相關(guān)細(xì)節(jié)。要將日志保存為可供計(jì)算機(jī)搜索的格式,就可以進(jìn)行關(guān)鍵字搜索以快速查找細(xì)節(jié)。圖 7-1 展示了一個(gè)簡(jiǎn)單的例子,其中帶有超鏈接以提供更多信息。圖7-1帶有超鏈接的解決方案條目示例如果面臨的問題無法在日志中找到解決方案,在問題解決之后,要記得馬上將新的細(xì)節(jié)記錄到日志中去。要共享日志給其他人,而不僅僅是靠一個(gè)人維護(hù)。把它放到共享的網(wǎng)絡(luò)驅(qū)動(dòng)器中,這樣其他人也可以使

45、用?;蛘邉?chuàng)建一個(gè)Wiki,并鼓勵(lì)其他開發(fā)人員使用和更新其內(nèi)容。維護(hù)一個(gè)問題及其解決方案的日志。保留解決方案是修復(fù)問題過程的一部分,以后發(fā)生相同或類似問題時(shí),就可以很快找到并使用了。切身感受解決方案日志應(yīng)該作為思考的一個(gè)來源,可以在其中發(fā)現(xiàn)某些特定問題的細(xì)節(jié)。對(duì)于某些類似但是有差異的問題,也能從中獲得修復(fù)的指引。平衡的藝術(shù)· 記錄問題的時(shí)間不能超過在解決問題上花費(fèi)的時(shí)間。要保持輕量級(jí)和簡(jiǎn)單,不必達(dá)到對(duì)外發(fā)布式的質(zhì)量。· 找到以前的解決方法非常關(guān)鍵。使用足夠的關(guān)鍵字,可以幫助你在需要的時(shí)候發(fā)現(xiàn)需要的條目。· 如果通過搜索Web,發(fā)現(xiàn)沒人曾經(jīng)遇到同樣的問題,也許搜索的方

46、式有問題。· 要記錄發(fā)生問題時(shí)應(yīng)用程序、應(yīng)用框架或平臺(tái)的特定版本。同樣的問題在不同的平臺(tái)或版本上可能表現(xiàn)得不同。· 要記錄團(tuán)隊(duì)做出一個(gè)重要決策的原因。否則,在69個(gè)月之后,想再重新回顧決策過程的時(shí)候,這些細(xì)節(jié)就很難再記得了,很容易發(fā)生互相指責(zé)的情形。 34習(xí)慣34:警告就是錯(cuò)誤“編譯器的警告信息只不過是給過分小心和過于書呆子氣的人看的。它們只是警告而已。如果導(dǎo)致的后果很嚴(yán)重,它們就是錯(cuò)誤了,而且會(huì)導(dǎo)致無法通過編譯。所以干脆忽略它們就是了?!?#160;當(dāng)程序中出現(xiàn)一個(gè)編譯錯(cuò)誤時(shí),編譯器或是構(gòu)建工具會(huì)拒絕產(chǎn)生可執(zhí)行文件。我們別無選擇必須要先修正錯(cuò)誤,再繼續(xù)前行。&#

47、160;然而,警告卻是另外一種狀況。即使代碼編譯時(shí)產(chǎn)生了警告,我們還是可以運(yùn)行程序。那么忽略警告信息繼續(xù)開發(fā)代碼,會(huì)導(dǎo)致什么狀況呢?這樣做等于是坐在了一個(gè)嘀嗒作響的定時(shí)炸彈上,而且它很有可能在最糟糕的時(shí)刻爆炸。有些警告是過于挑剔的編譯器的良性副產(chǎn)品,有些則不是。例如,一個(gè)關(guān)于未被使用的變量的警告,可能不會(huì)產(chǎn)生什么惡劣影響,但卻有可能是暗示某些變量被錯(cuò)誤使用了。 最近在一家客戶那里,Venkat發(fā)現(xiàn)一個(gè)開發(fā)中的應(yīng)用有多于300個(gè)警告。其中一個(gè)被開發(fā)人員忽略的警告是這樣: Assignment in conditional expression is always consta

48、nt;did you mean to use = instead of = ?條件表達(dá)式中的賦值總為常量,你是否要使用=而不是=? 相關(guān)代碼如下: if (theTextBox.Visible = true).也就是說,if 語句總是會(huì)評(píng)估為true,無論不幸的theTextBox變量是什么狀況。看到類似這樣真正的錯(cuò)誤被當(dāng)作警告忽略掉,真是令人感到害怕。 看看下面的C#代碼: public class Base  public virtual void foo()  

49、0;   Console.WriteLine("Base.foo ");   public class Derived : Base    public virtual void foo()      Console.WriteLine("Derived.foo ");   class Test  static void Main(str

50、ing args)      Derived d = new Derived();    Base b = d;    d.foo();    b.foo();   在使用Visual Studio 2003默認(rèn)的項(xiàng)目設(shè)置對(duì)其進(jìn)行編譯時(shí),會(huì)看到如此信息“構(gòu)建:1個(gè)成功,0失敗,0 跳過”顯示在Output窗口的底部。運(yùn)行程序,會(huì)得到這樣的輸出: Derived.fooBase.foo 但這不是我們預(yù)期的結(jié)果。應(yīng)該看到

51、兩次對(duì)Derived類中foo方法的調(diào)用。是哪里出錯(cuò)了?如果仔細(xì)查看 輸出窗口,可以發(fā)現(xiàn)這樣的警告信息:Warning. Derived.foo hides inherited member Base.fooTo make the current member override that implementation,add the override keyword. Otherwise, you' d add the new keyword. 這明顯是一個(gè)錯(cuò)誤在 Derived 類的foo()方法中,應(yīng)該使用override 而不是 virtu

52、al。1想象一下,有組織地忽略代碼中類似這樣的錯(cuò)誤會(huì)導(dǎo)致什么樣的后果。代碼的行為會(huì)變得無法預(yù)測(cè),其質(zhì)量會(huì)直線下降。可能有人會(huì)說優(yōu)秀的單元測(cè)試可以發(fā)現(xiàn)這些問題。是的,它們可以起到幫助作用(而且也應(yīng)該使用優(yōu)秀的單元測(cè)試)??扇绻幾g器可以發(fā)現(xiàn)這種問題,那為什么不利用它呢?這可以節(jié)省大量的時(shí)間和麻煩。要找到一種方式讓編譯器將警告作為錯(cuò)誤提示出來。如果編譯器允許調(diào)整警告的報(bào)告級(jí)別,那就把級(jí)別調(diào)到最高,讓任何警告不能被忽略。例如, GCC編譯器支持 -Werror 參數(shù),在 Visual Studio 中,開發(fā)人員可以改變項(xiàng)目設(shè)置,將警告視為錯(cuò)誤。 對(duì)于一個(gè)項(xiàng)目的警告信息來

53、說,至少也要做到這種地步。然而,如果采取這種方式,就要對(duì)創(chuàng)建的每個(gè)項(xiàng)目去進(jìn)行設(shè)置。如果可以盡量以全局化的方式來進(jìn)行設(shè)置就好了。比如,在Visual Studio中,開發(fā)人員可以修改項(xiàng)目模板(查看.NET GotchasSub05獲取更多細(xì)節(jié)),這樣在計(jì)算機(jī)上創(chuàng)建的任何項(xiàng)目,都會(huì)有同樣的完整項(xiàng)目設(shè)置。在當(dāng)前版本的Eclipse中,可以按照這樣的順序修改設(shè)置:WindowsPreferencesJavaCompilerErrors/Warnings。如果使用其他的語言或IDE,花一些時(shí)間來找出如何在其中將警告作為錯(cuò)誤處理吧。在修改設(shè)置的時(shí)候,要記得在構(gòu)建服務(wù)器上使用的持續(xù)集成工具中,修改同樣的設(shè)置

54、選項(xiàng)。(要詳細(xì)了解持續(xù)集成,查看在第87頁上的習(xí)慣21。)這個(gè)小小的設(shè)置,可以大大提升團(tuán)隊(duì)簽入到源碼控制系統(tǒng)中的代碼質(zhì)量。在開始一個(gè)項(xiàng)目的時(shí)候,要把相關(guān)的設(shè)置都準(zhǔn)備好。在項(xiàng)目進(jìn)行到一半的時(shí)候,突然改變警告設(shè)置,有可能會(huì)帶來顛覆性的后果,導(dǎo)致難以控制。編譯器可以輕易處理警告信息,可是你不能。將警告視為錯(cuò)誤簽入帶有警告的代碼,就跟簽入有錯(cuò)誤或者沒有通過測(cè)試的代碼一樣,都是極差的做法。簽入構(gòu)建工具中的代碼不應(yīng)該產(chǎn)生任何警告信息。切身感受警告給人的感覺就像哦,警告。它們就某些問題給出警告,來吸引開發(fā)人員的注意。平衡的藝術(shù)· 雖然這里探討的主要是編譯語言,解釋型語言通常也有標(biāo)志,允許運(yùn)行時(shí)警告

55、。使用相關(guān)標(biāo)志,然后捕獲輸出,以識(shí)別并最終消除警告。· 由于編譯器的bug或是第三方工具或代碼的原因,有些警告無法消除。如果確實(shí)沒有應(yīng)對(duì)之策的話,就不要再浪費(fèi)更多時(shí)間了。但是類似的狀況很少發(fā)生。· 應(yīng)該經(jīng)常指示編譯器:要特別注意別將無法避免的警告作為錯(cuò)誤進(jìn)行提示,這樣就不用費(fèi)力去查看所有的提示,以找到真正的錯(cuò)誤和警告。· 棄用的方法被棄用是有原因的。不要再使用它們了。至少,安排一個(gè)迭代來將它們(以及它們引起的警告信息)安全地移除掉。· 如果將過去開發(fā)完成的方法標(biāo)記為棄用方法,要記錄當(dāng)前用戶應(yīng)該采取何種變通之策,以及被棄用的方法將會(huì)在何時(shí)一起移除。1這對(duì)C

56、+程序員來講是一個(gè)潛伏的陷阱。在C+中代碼可以按預(yù)期方式工作。35習(xí)慣35:對(duì)問題各個(gè)擊破“逐行檢查代碼庫中的代碼確實(shí)很令人恐懼。但是要調(diào)試一個(gè)明顯的錯(cuò)誤,只有去查看整個(gè)系統(tǒng)的代碼,而且要全部過一遍。畢竟你不知道問題可能發(fā)生在什么地方,這樣做是找到它的唯一方式?!眴卧獪y(cè)試(在第76頁,第5章)帶來的積極效應(yīng)之一,是它會(huì)強(qiáng)迫形成代碼的分層。要保證代碼可測(cè)試,就必須把它從周邊代碼中解脫出來。如果代碼依賴其他模塊,就應(yīng)該使用mock對(duì)象,來將它從其他模塊中分離開。這樣做不但讓代碼更加健壯,且在發(fā)生問題時(shí),也更容易定位來源。否則,發(fā)生問題時(shí)有可能無從下手。也許可以先使用調(diào)試器,逐行執(zhí)行代碼,并試圖隔離

57、問題。也許在進(jìn)入到感興趣的部分之前,要運(yùn)行多個(gè)表單或?qū)υ捒?,這會(huì)導(dǎo)致更難發(fā)現(xiàn)問題的根源。你會(huì)發(fā)現(xiàn)自己陷入整個(gè)系統(tǒng)之中,徒然增加了壓力,而且降低了工作效率。大型系統(tǒng)非常復(fù)雜在執(zhí)行過程中會(huì)有很多因素起作用。從整個(gè)系統(tǒng)的角度來解決問題,就很難區(qū)分開,哪些細(xì)節(jié)對(duì)要定位的特定問題產(chǎn)生影響,而哪些細(xì)節(jié)沒有。答案很清晰:不要試圖馬上了解系統(tǒng)的所有細(xì)節(jié)。要想認(rèn)真調(diào)試,就必須將有問題的組件或模塊與其他代碼庫分離開來。如果有單元測(cè)試,這個(gè)目的就已經(jīng)達(dá)到了。否則,你就得開動(dòng)腦筋了。比如,在一個(gè)時(shí)間緊急的項(xiàng)目中(哪個(gè)項(xiàng)目的時(shí)間不緊急呢),F(xiàn)red和George發(fā)現(xiàn)他們面對(duì)的是一個(gè)嚴(yán)重的數(shù)據(jù)損毀問題。要花很多精力才能知

58、道哪里出了問題,因?yàn)殚_發(fā)團(tuán)隊(duì)沒有將數(shù)據(jù)庫相關(guān)的代碼與其他的應(yīng)用代碼分離開。他們無法將問題報(bào)告給軟件廠商,當(dāng)然不能把整個(gè)代碼庫用電子郵件發(fā)給人家!于是,他們倆開發(fā)了一個(gè)小型的原型系統(tǒng),并展示了類似的癥狀;然后將其發(fā)送給廠商作為實(shí)例,并詢問他們的專家意見,使用原型幫助他們對(duì)問題理解得更清晰。而且,如果他們無法在原型中再現(xiàn)問題的話,原型也可以告訴他們可以工作的代碼示例,這也有助于分離和發(fā)現(xiàn)問題。識(shí)別復(fù)雜問題的第一步,是將它們分離出來。既然不可能在半空中試圖修復(fù)飛機(jī)引擎,為什么還要試圖在整個(gè)應(yīng)用中,診斷其中某個(gè)組成部分的復(fù)雜問題呢?當(dāng)引擎被從飛機(jī)中取出來,而且放在工作臺(tái)上之后,就更容易修復(fù)了。同理,如

59、果可以隔離出發(fā)生問題的模塊,也更容易修復(fù)發(fā)生問題的代碼。    分離原型                          Prototype to isolate可是,很多應(yīng)用的代碼在編寫時(shí)沒有注意到這一點(diǎn),使得分離變得特別困難。應(yīng)用的各個(gè)構(gòu)成部分之間會(huì)彼此糾結(jié):想把這個(gè)部分單獨(dú)拿出來,其他的會(huì)緊隨而至。在這些狀況下

60、,最好花一些時(shí)間把關(guān)注的代碼提取出來,而且創(chuàng)建一個(gè)可讓其工作的測(cè)試環(huán)境。對(duì)問題各個(gè)擊破,這樣做有很多好處:通過將問題與應(yīng)用其他部分隔離開,可以將關(guān)注點(diǎn)直接放在與問題相關(guān)的議題上;可以通過多種改變,來接近問題發(fā)生的核心你不可能針對(duì)正在運(yùn)行的系統(tǒng)來這樣做。可以更快地發(fā)現(xiàn)問題的根源所在,因?yàn)橹慌c所需最小數(shù)量的相關(guān)代碼發(fā)生關(guān)系。隔離問題不應(yīng)該只在交付軟件之后才著手。在構(gòu)建系統(tǒng)原型、調(diào)試和測(cè)試時(shí),各個(gè)擊破的戰(zhàn)略都可以起到幫助作用。對(duì)問題各個(gè)擊破在解決問題時(shí),要將問題域與其周邊隔離開,特別是在大型應(yīng)用中。切身感受面對(duì)必須要隔離的問題時(shí),感覺就像在一個(gè)茶杯中尋找一根針,而不是大海撈針。平衡的藝術(shù) ·

61、; 如果將代碼從其運(yùn)行環(huán)境中分離后,問題消失不見了,這有助于隔離問題。· 另一方面,如果將代碼從其運(yùn)行環(huán)境中分離后,問題還在,這也有助于隔離問題。 · 以二分查找的方式來定位問題是很有用的。也就是說,將問題空間分為兩半,看看哪一半包含問題。再將包含問題的一半進(jìn)行二分,并不斷重復(fù)這個(gè)過程。· 在向問題發(fā)起攻擊之前,先查找你的解決問題日志 36習(xí)慣36:報(bào)告所有的異常"不要讓程序的調(diào)用者看到那些奇怪的異常。處理它們是你的責(zé)任。把你調(diào)用的一切都包起來,然后發(fā)送自己定義的異常-或者干脆自己解決掉。"從事任何編程工作,都要考慮事物正常狀況下是如何運(yùn)作的。不過更應(yīng)該想一想,當(dāng)出現(xiàn)問題-也就是事情沒有按計(jì)劃進(jìn)行時(shí),會(huì)發(fā)生什么。在調(diào)用別人的代碼時(shí),它也許會(huì)拋異常,這時(shí)我們

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論