作 者: (美)古德利弗(Goodliffe, P.)著 韓江,陳玉 譯
出 版 社: 電子工業出版社
出版時間: 2008-9-1
字 數: 840000
頁 數: 620
開 本: 16開
I S B N : 9787121069802
分類: 圖書 >> 計算機/網路 >> 軟體工程/開發項目管理
定價:¥79.00
內容簡介
如果你可以編寫出合格的代碼,但是想更進一步、創作出組織良好而且易於理解的代碼,並希望成為一名真正的編程專家或提高現有的職業技能,那么《編程匠藝——編寫卓越的代碼》都會為你給出答案。本書的內容遍及編程的各個要素,如代碼風格、變數命名、錯誤處理和安全性等。此外,本書還對一些更廣泛的編程問題進行了探討,如有效的團隊合作、開發過程和文檔編寫,等等。本書各章的末尾均提供一些思考問題,這些問題回顧了各章中的一些關鍵概念,可以促使你像專家一樣思考,從而使本書成為那些渴望作為團隊的一分子,職業並高效地編程的新手們的一本絕佳的參考書。
作者簡介
Pete Goodliffe是一位軟體開發專家,他在軟體“食物鏈”上從未駐足不前。他在各種各樣的項目中使用過許多種語言。他還在教授和指導程式設計師方面有著豐富的經驗,並且常年為ACCU的C Vu雜誌(www.accu.org)撰寫欄目“編程的職業化”。Pete痴迷於編寫出色的、沒有錯誤的代碼,這使得他有更多的時間與自己的孩子共度美好時光.
推 薦 序
——打造開發者的核心競爭力
信息產業幾乎是開放程度最高的產業,其發展之快,讓身處其中的我們既感到興奮和激動,也時常困惑和惶恐。信息技術的變化太快、太激烈,一切都在迅速革新當中,作為技術人員,我們今天熟悉並且賴以安身立命的東西,很快就會變成故紙堆里的古董。人生總是需要不斷積累才能越走越高的,如果找不到一項可以積累提升、而且被市場所承認的核心競爭力,事業的大廈是建不起來的。於是一個嚴峻的問題就擺在每一個技術人員的面前——什麼才是我們的核心競爭力?
二十年前,人們認為軟體開發者的核心競爭力應該體現在他的聰明才智和紮實的基本功上,要精通算法、硬體、編譯、計算機體系結構,要有天馬行空般的想像力和創造力,能夠單槍匹馬單打獨鬥。至於什麼團隊協作、編碼規範、單元測試、最佳實踐,都是對天才的不必要的羈絆。
大約到了20世紀90年代中期,風水變了。隨著軟體的規模越來越大,以及當代作業系統、面向對象技術、軟體開發工具、程式庫和框架的普及,“平台”和“工具”變得越來越重要了。大多數時候,開發者不需要自己從頭實現所有功能,他所依賴的平台已經準備好了現成的組件供使用,有的時候甚至應用程式中最繁瑣、最複雜的部分已經由框架或程式庫實現好了。因此,人們普遍認為,一個開發者的核心競爭力很大程度上表現為對平台與工具的理解和掌握,並依託這種理解創造性地構築產品,或者更確切地說,一種創造性地組裝產品的能力。你還在為剛剛琢磨出來的一個高效算法而得意嗎?旁邊那位藉助程式庫里提供的組件,已經快速地完成了整個功能模組;你發明了一個新的視頻格式以及對應的codec?很了不起!不過另一個初出茅廬、連快速傅立葉變換算法都寫不出來的團隊已經基於sourceforge上的開源組件做出產品來,並且播得滿網際網路都是了。當然,黑客們仍然有著不可取代的價值,總是能找到自己的位置;但是對於那些強調團隊作戰、快速行動的企業來說,一個熟練掌握MFC、Delphi、J2EE、ASP.NET或者LAMP的開發者可能更實用,能更有效地為企業帶來價值。因此,這樣的程式設計師便一時成為企業的寵兒,眾人眼中的高手。
然而不到十年下來,問題又出現了。流行的平台和工具如走馬燈般你方唱罷我登場:昨天還在為領悟了MFC、Delphi而沾沾自喜,今天就發現套用主流已經是Web了;剛剛啃完艱深的EJB2,抬眼一看卻發現它已經被Spring的擁躉們批倒批臭了;上個月還是沖在敏捷Java領域的改革派,這個月就被一群嘴上無毛的ROR冬粉給劃到改革的對立面去了;ASP.NET還沒學踏實呢,微軟又準備好ASP.NET MVC、asp.net ajax、Silverlight等等一大堆新玩意讓你啃了。這樣下去,什麼時候是個頭?把自己的核心競爭力建立在這些轉瞬即逝的曇花上,難道不是把有限的生命投入到無限的瞎折騰之中嗎?難道只有鑽到一間舒舒服服的大公司里,到了三十多歲就尋求所謂的“轉型”,順著一條十分確鑿的“職場路線”攀或是混,最後在公司沒有倒閉或者自己沒有被“戰略裁員”的幸運之下頭頂玻璃天花板光榮退休,才是中國程式設計師的歸宿?什麼才是程式設計師可以長期積累,不斷提高,不但足以安身立命,而且能夠實現夢想、成就事業的核心競爭力呢? 回答好這個問題,對於今天的開發者來說,可能比掌握和精通某項具體技術意義重大得多。
在我看來,當代程式設計師的核心競爭力至少應該體現在這么幾點上:有紮實的基本功,活躍的想像力與創造力,快速的學習能力,具備行業和領域知識,以及專業的軟體工藝能力。而在這其中,專業軟體技能是最基本、也是最重要的一項。
什麼是專業軟體技能呢?就是正確地開發軟體的能力,更具體地說,是通過一系列有組織的、有原則、流程化、可檢驗、可重複的實踐行為,協作式開發高質量程式的能力。對於一個程式設計師來說,這是你的看家老本,對於一個軟體團隊來說,這是你們的立足之基。算法不會,可以查資料慢慢掌握;不理解行業,可以邊做邊學,逐漸深入;缺乏創新,可以站在巨人肩膀上耐心摸索;甚至基本功不足,也可以自我彌補,可是如果沒有做軟體的專業態度和實踐技能,沒有製作合格軟體的工藝水平,連一段高質量的程式都寫不出來,試問你還剩下什麼?
經過近三十年的時間,人們最終認識到,在規模化團隊協作的情況下,決定軟體產品質量的不再是個人的聰明才智,也不是靠什麼神仙技術,而是團隊的工藝實踐。是否在一開始就形成了開發計畫?是否對這個計畫進行了必要的確認、維護和跟蹤?必要的規範文檔是否撰寫了?是否形成了合理的架構?是否恰當地選擇了開發工具和程式語言?是否建構了適於團隊漸進協作的良好的工具和工作平台?是否一開始就形成了有力的缺陷核查、控制和跟蹤策略並始終嚴格地執行?是否制定了連續一致的編碼標準,並且通過諸如代碼走查等加以保證?是否有完整的測試製度?是否具有明確的性能最佳化和軟體安全性保障過程?是否在整個生命周期貫徹了嚴格的版本管理、配置管理、發布管理和軟體維護退役管理措施?這些實實在在的問題,是需要耐心與細心地用具體實踐細節來回答的。當一個團隊對於這些問題都給出了明確而一致的回答並且用行動來執行的時候,他們就是一個專業的、具有核心競爭力的團隊。而當一個個體開發者能夠對這些問題具備正確的觀念,並且通過施加自己的影響力促進團隊向正確的方向前進的時候,他就是一個具有核心競爭力的開發者。一個具有核心競爭力的團隊和開發者,是可以不斷進步的,是具備把握機遇的能力的;一旦時機合適,他們就完全有可能實現更大的目標。
十多年以前國內外軟體界對工藝的問題並不重視。大部分人要么執迷於技術本身,指望某一天一個面向某某的技術能夠一勞永逸的解決軟體開發中的所有問題,要么就是把問題大而化之為“軟體工程”,企圖以指令性的方式,在巨觀的層面上用管理取代工藝。在這兩個方向上,程式設計師要么被視為可以充分放縱的孤膽英雄,要么被視為偉大編程技術最終出現之前不得不存在的過渡品,或者管理指令的機械的執行體,“人”的維度消失了。這種對於人和工藝細節的忽視也體現在技術著作方面。軟體工程、面向對象、編程技巧和產品手冊之類的著作汗牛充棟,而認真談到軟體工藝的書屈指可數。
直到20世紀90年代中期,隨著一些軟體產品的規模越來越大,微軟率先認識到工藝問題的重要性,於是出版了諸如《代碼大全》、《編寫清晰的代碼》等一系列探討這一問題的著作。直到20世紀90年代末期,當整個工業界從面向對象和軟體工程的幻影泡沫中走出來之後,才開始認真全面地審視軟體工藝的問題,而且通過敏捷運動、把軟體工藝的重要性和基本實踐提到了一個令人矚目的位置上。事實上,敏捷運動可以認為是軟體工藝的復興運動。此外,隨著《代碼大全2》、《軟體工藝》、《代碼閱讀》、《程式設計師修煉之道》等經典作品的出版,在技術圖書領域也陸續出現了一批專門探討軟體工藝的著作。這本《編程匠藝》也是這個領域中的一本佳作。
本書是一部全面討論軟體構造工藝實踐的著作,從軟體開發的計畫到架構設計,從編碼風格規範到軟體缺陷的檢測與管理,從程式設計師工具箱的配備到團隊協作精神的塑造,這本書都給予了翔實、風趣而具有啟發性的討論。這些討論,既有原則性、理論性一面,也有技術性的具體建議,對於團隊領導者、高級開發者和每一個希望快速進步的程式設計師具有明確的指導意義。如果讀者認同軟體工藝的重要性,那么可以說這本書是幫助讀者建構自己核心競爭力的一本難得的作品。特別值得一提的是,這本書中文版的翻譯流暢自然,在很多地方都體現出譯者的認真態度和翻譯功力。對於一本翻譯自英文的技術著作來說,這無疑是一個大大的加分。
當然,一本書的覆蓋面和功效畢竟是有限的,核心競爭力的確立和建構歸根到底是一個艱苦實踐的過程,不同性格的人也一定有著不同的目標和方式。但是我相信,對於有心人來說,只要我們不斷地探索和實踐,都會獲得自己的核心競爭力,做一個有準備的人,爭取和等待機會的垂青,最終實現自己的人生目標。
讀此書有感而發,借題發揮,是為評論。
譯 者 序
作為從事軟體開發的程式設計師,你肯定遇到過這樣的情況:自認為完美的代碼,在項目快要結束的時候,卻總是會發現還有好多內容需要修改。更有甚者,由於人員的變動,那些他們遺留下來的“老代碼”,作為時間留給程式設計師與項目組的最大遺產,卻可能會成為項目組的災難。
除了受制於人類自身的缺陷之外,還有由於組織而帶來的問題,如客戶需求不斷變更、必須在有限的時間和預算之內完成項目,來自內部所謂“項目管理”的種種壓力,等等。天哪,這些問題我們絕大部分人都趕上了。
列寧曾在監獄中寫下了《怎么辦?》,指導了俄國的十月革命。而在軟體業,從一代宗師Frederick P. Brooks的《人月神話》開始,就在找“怎么辦”這個“銀彈”了。然而,“狼來了”在多次被喊出來後,已經很少有人相信了。我們必須承認,這些都是根本層面的問題,目前還不能得到解決。但是,本書的作者Pete Goodliffe認為,至少我們可以採取一些方式,減少一些開發上的痛苦。因為,除了開發,人生還有許多更為美好的事物在等著我們。我們這次也可以高喊“銀彈來了”。沒有最好,只有更好,誰知道這次不是真的呢?
著名國畫大師齊白石在年輕的時候,曾經做過木匠。據說有一次他和師傅去給地主幹活,在路上迎面走來另外一對木匠師徒。齊先生的師傅說,趕緊給別人讓路。師徒倆站在路邊,老師恭敬地目送那兩人漸漸走遠。齊白石不解,問師傅:同是木匠,你我師徒為什麼要給他們讓路。老師傅回頭說:為什麼?別人是做細活的,我們是做粗活的。
Pete Goodliffe在業界的年頭快要超過好多人的年齡了,此君曾經涉獵多個領域、不同的程式語言以及多種架構,並且曾經在採用不相同流程的公司里從事開發。在本書中,他把多年壓箱底的一些觀念想法和技巧告訴了大家,這些都是時間與智慧的結合,相信無論是開發人員、項目經理甚至測試人員,都可以從中發現阿里巴巴開啟金庫的鑰匙。
那么本書有什麼特色呢?對於想了解內容的普通讀者來說,本書至少有以下特點:
1.貼近實際 《編程匠藝——編寫卓越的代碼》是本書的書名,但也是作者的用心所在。人生有三個境界,最後一個就是“看山是山,看水是水”。這是廢話嗎?當然不是,作者對此給出了最好的解答。作為程式設計師,我們最喜歡爭論不同工具、平台、方法之間的優劣。而作者卻通過多年經驗,力圖告訴我們應該如何提高質量,並成為一名優秀的程式設計師。這些方法就像點石成金的手指,它們是方法論,而不是針對具體的工具或者平台的說教。我們現在所缺的,恰恰是這些能使自己更進一階的手段,而不是那些特殊的技術細節。
2.內容豐富翔實 很少有一本書能涵蓋如此多的領域,並且還如此紮實。作為一名程式設計師,我們可能永遠無法達到完美。而需要處於一種持續不斷地提高的狀態,總會有更多的東西需要學習。那么下一步應該做什麼呢?這裡就有答案。
3.可作為“秘要心法” 本書不僅適合入門者,也適合需要提高的開發人員,以及那些想管理好所謂代碼猴子的項目經理們。與《項目經理案頭手冊》一樣,這本書也將成為每人的案頭手冊或者枕邊書,可以作為應急或者提升的手段。如果以後碰到了問題,可以隨時參閱相關的章節。
4.心態決定一切 這句話對嗎?有了良好心態,不一定行,如果沒有,肯定不行。我們常常羨慕於老外以四五十歲的年紀仍然能繼續從事編程,為什麼我們不行呢?可能不同的讀者都會找到屬於自己的答案!Pete Goodliffe具有寬闊的視野,紮實的基礎,廣泛的愛好,帶有一種程式設計師應該具有的高雅和恬淡。這正是我們這個浮躁的時代中積極探索的一代程式設計師所不具備的。
最後禁不住要抱怨一下,作者Pete Goodliffe以他豐富的閱歷和愛好,給譯者帶來了不小的麻煩,比如出於它對於音樂的愛好,所有章節的標題都來自英國的歌曲名稱。為了理解上的直觀,我們在翻譯的過程中採取的是“信達雅”中的“雅”,以保證國內讀者能很快切入主題。本書每章開始和行文的過程中,作者都引用了歷史上或者現在社會中一些名人的名言,這給翻譯增加了不少的難度,但是由於貼切精闢,這些名言也可稱之為點睛之筆。尤為值得高興的是,此君對我中華文化竟然也有一定的造詣,孔夫子和老子的哲理名言竟然多次出現,而且能夠貼切地表達出這些聖人的思想對軟體開發有哪些啟示,這非常不簡單,難為了作者,也著實難為了譯者。從外國作者的筆下,讓我們著實體會到了自己國家的文化源遠流長。這從一個側面也體現出東海西海,千聖一心。
此書給了我們一個快速成功進階的好範例。我覺得它更像一個程式設計師的入門或者修行心法。從此入門,我們可以少走很多彎路。同時,我們也要爭取像佛經中“般若波羅密”所講的那樣:大智慧到彼岸,最後連佛法也像渡河的筏子一樣,成佛後立即丟棄。我更希望的是,看過此書的讀者們,最後能夠拍案而起,大聲說:我可以了。
圖書目錄
第I篇 代碼表面第一部分
第1章 善於防守——健壯代碼的防禦性編程技巧 3
1.1 向優秀的代碼前進 4
1.2 構想:最壞的選擇 4
1.3 什麼是防禦性編程 6
1.4 又大又壞的世界 8
1.5 防禦性編程技巧 8
1.5.1 使用好的編碼風格和合理的設計 9
1.5.2 不要倉促地編寫代碼 9
1.5.3不要相信任何人10
1.5.4 編碼的目標是清晰,而不是簡潔 10
1.5.5 不要讓任何人做他們不該做的修補工作 11
1.5.6 編譯時打開所有警告開關 11
1.5.7 使用靜態分析工具 12
1.5.8 使用安全的數據結構 12
1.5.9 檢查所有的返回值 13
1.5.10 審慎地處理記憶體(和其他寶貴的資源) 13
1.5.11 在聲明位置初始化所有變數 14
1.5.12 儘可能推遲一些聲明變數 14
1.5.13 使用標準語言工具 14
1.5.14 使用好的診斷信息日誌工具 15
1.5.15 審慎地進行強制轉換 15
1.5.16 細則 15
1.6 約束 16
1.6.1 約束的內容 17
1.6.2 移除約束 18
1.7 總結 20
1.8 另請參見 20
1.9 思考 21
1.9.1 深入思考 21
1.9.2 結合自己 22
第2章 精心布局——原始碼的版面和樣式 23
2.1 什麼是關鍵 24
2.2 了解你的讀者 25
2.3 什麼是好的樣式 26
2.4 使用括弧 26
2.4.1 K&R括弧風格 27
2.4.2 懸掛式的括弧風格 27
2.4.3 縮進的括弧風格 29
2.4.4 其他的括弧風格 29
2.5 主宰一切的風格 30
2.6 內部風格(以及在哪裡使用它們) 31
2.7 設立標準 33
2.8 正義的戰爭 35
2.9 總結 35
2.10 另請參見 37
2.11 思考 37
2.11.1 深入思考 37
2.11.2 結合自己 38
第3章 名正言順——為有意義的事物起有意義的名稱 39
3.1 為什麼我們應該恰當地命名呢 41
3.2 我們對什麼進行命名 41
3.3 名字遊戲 42
3.3.1 描述性 42
3.3.2 技術上正確 42
3.3.3 符合語言習慣 43
3.3.4 恰當 43
3.4 具體細節 44
3.4.1 命名變數 44
3.4.2 命名函式 45
3.4.3 命名類型 46
3.4.4 命名名字空間 47
3.4.5 命名宏 48
3.4.6 命名檔案 48
3.5 玫瑰不叫玫瑰 49
3.5.1 保持前後一致 50
3.5.2 利用上下文 51
3.5.3 使用對你有利的名稱 51
3.6 總結 52
3.7 另請參見 53
3.8 思考 53
3.8.1 深入思考 54
3.8.2 結合自己 55
第4章 不言自明——編寫“自文檔化”代碼的技巧 57
4.1 自文檔化的代碼 59
4.2 編寫自文檔化代碼的技術 61
4.2.1 使用好的樣式編寫簡單的代碼 61
4.2.2 選擇有意義的名稱 62
4.2.3 分解為原子函式 62
4.2.4 選擇描述性的類型 63
4.2.5 命名常量 63
4.2.6 強調重要的代碼 64
4.2.7 分組相關信息 64
4.2.8 提供檔案頭 64
4.2.9 恰當地處理錯誤 65
4.2.10 編寫有意義的注釋 65
4.3 實用的自文檔化方法 66
4.3.1 文學性編程 66
4.3.2 文檔化工具 67
4.4 總結 69
4.5 另請參見 70
4.6 思考 71
4.6.1 深入思考 71
4.6.2 結合自己 72
第5章 隨篇注釋——如何編寫代碼注釋 73
5.1 什麼是代碼注釋 74
5.2 注釋看上去是什麼樣的 75
5.3 多少注釋是恰當的 75
5.4 注釋中應該有些什麼 76
5.4.1 解釋為什麼,而不是怎么樣 76
5.4.2 不要描述代碼 76
5.4.3 不要取代代碼 76
5.4.4 確保注釋有用 77
5.4.5 避免分心 78
5.5 實踐 79
5.6 從審美的角度看注釋 80
5.6.1 一致性 80
5.6.2 清晰的塊注釋 80
5.6.3 縮進的注釋 81
5.6.4 行章節附注釋 81
5.6.5 幫助你閱讀代碼 81
5.6.6 選擇一種維護成本較低的風格 82
5.6.7 分隔板 82
5.6.8 標誌 83
5.6.9 檔案頭注釋 83
5.7 使用注釋 84
5.7.1 幫助你編寫例行程式 84
5.7.2 錯誤修正通告 85
5.7.3 注釋過時 85
5.7.4 維護和空洞無物的注釋 86
5.8 總結 86
5.9 另請參見 87
5.10 思考 87
5.10.1 深入思考 88
5.10.2 結合自己 88
第6章 人非聖賢——處理不可避免的情況——代碼中的錯誤情形 89
6.1 從何而來 90
6.2 錯誤報告機制 91
6.2.1 不報告 91
6.2.2 返回值 92
6.2.3 錯誤狀態變數 93
6.2.4 異常 93
6.2.5 信號 95
6.3 檢測錯誤 95
6.4 處理錯誤 96
6.4.1 何時處理錯誤 97
6.4.2 可能的反應 98
6.4.3 代碼示例 100
6.5 使地獄浮現 104
6.6 管理錯誤 105
6.7 總結 106
6.8 另請參見 107
6.9 思考 107
6.9.1 深入思考 107
6.9.2 結合自己 108
第II篇 代碼的神秘生命
第7章 欲善其事,先利其器——使用工具構建軟體 111
7.1 什麼是軟體工具 112
7.2 為什麼要在意工具 114
7.3 使工具發揮作用 115
7.3.1 了解它能做些什麼 115
7.3.2 學習如何駕馭它 116
7.3.3 了解它適合什麼任務 116
7.3.4 檢查它是否可用 116
7.3.5 找到了解更多信息的途徑 117
7.3.6 查明新版本何時出現 117
7.4 哪個工具 117
7.4.1 原始碼編輯工具 118
7.4.2 代碼構建工具 120
7.4.3 調試和調查工具 123
7.4.4 語言支持工具 124
7.4.5 其他工具 125
7.5 總結 126
7.6 另請參見 127
7.7 思考 128
7.7.1 深入思考 128
7.7.2 結合自己 128
第8章測試時代——測試代碼的魔術 129
8.1 反思現實 131
8.2 誰、是什麼、何時以及為什麼 132
8.2.1 我們為什麼要測試 132
8.2.2 誰來進行測試 133
8.2.3 測試的內容有些什麼 133
8.2.4 何時進行測試 134
8.3 測試並不難…… 135
8.4 測試的類型 138
8.5 選擇單元測試用例 142
8.6 為測試而設計 144
8.7 看!不要用手! 144
8.8 面對故障該怎么辦 145
8.9 你能管理它嗎 146
8.9.1缺陷跟蹤系統147
8.9.2 bug審查 148
8.10 總結 149
8.11 另請參見 150
8.12 思考 150
8.12.1 深入思考 150
8.12.2 結合自己 151
第9章 尋找缺陷——調試:當事情進展得不順利時該怎么辦 153
9.1 生活的真相 154
9.2 bug的種類 155
9.2.1 從遠處看 155
9.2.2 從近處看 156
9.2.3 從更近處看 158
9.3 消滅害蟲 160
9.3.1 地下之路 161
9.3.2 地上之路 161
9.4 搜尋bug 162
9.4.1 編譯時錯誤 162
9.4.2 運行時錯誤 164
9.5 如何修正缺陷 167
9.6 預防 169
9.7 除蜂劑、驅蟲劑、捕蠅紙 169
9.7.1 調試器 169
9.7.2 記憶體訪問校驗器 170
9.7.3 系統調用跟蹤 170
9.7.4 核心轉儲 170
9.7.5 日誌 170
9.8 總結 171
9.9 另請參見 172
9.10 思考 173
9.10.1 深入思考 173
9.10.2 結合自己 173
第10章 代碼構建——將原始碼轉換為可執行代碼的過程 175
10.1 語言障礙 176
10.1.1解釋型語言177
10.1.2編譯型語言178
10.1.3 位元組編譯型語言 179
10.2 小題大做 179
10.3 構建軟體版本 181
10.4 怎樣才算是一個優秀的構建系統 184
10.4.1 簡潔 184
10.4.2 一致 184
10.4.3 可重複和可靠 185
10.4.4 原子性 186
10.4.5 能夠應付錯誤 187
10.5 技術細節 187
10.5.1 目標的選擇 187
10.5.2 內務處理 189
10.5.3 依賴關係 189
10.5.4 自動構建 190
10.5.5 構建配置 191
10.5.6 遞歸地使用make 192
10.6 請發布我吧 192
10.7 構建大師是全能的嗎 194
10.8 總結 195
10.9 另請參見 195
10.10 思考 196
10.10.1 深入思考 196
10.10.2 結合自己 196
第11章 追求速度——最佳化程式和編寫高效的代碼 199
11.1 最佳化是什麼 200
11.2 是什麼使代碼不盡如人意 201
11.3 為什麼不進行最佳化呢 202
備選方案 204
11.4 為什麼要進行最佳化 205
11.5 最佳化的具體細節 206
11.5.1 證明你需要進行最佳化 206
11.5.2 找出運行得最慢的代碼 207
11.5.3 測試代碼 208
11.5.4 最佳化代碼 209
11.5.5 最佳化之後 209
11.6 最佳化的技術 210
11.6.1 設計更改 210
11.6.2 代碼更改 213
11.7 編寫高效的代碼 217
11.8 總結 219
11.9 另請參見 219
11.10 思考 220
11.10.1 深入思考 220
11.10.2 結合自己 221
第12章 不安全感綜合症——編寫安全的程式 223
12.1 危險 224
12.2 敵人 226
12.3 藉口,都是藉口 228
12.4 感到很脆弱 229
12.4.1 不安全的設計和體系結構 229
12.4.2 緩沖溢出 229
12.4.3 嵌入的查詢字元串 230
12.4.4 競爭狀況 231
12.4.5 整數溢出 231
12.5 防範措施 232
12.5.1 系統安裝技術 233
12.5.2 軟體設計技術 234
12.5.3 代碼實現技術 235
12.5.4 規程技術 236
12.6 總結 236
12.7 另請參見 237
12.8 思考 238
12.8.1 深入思考 238
12.8.2 結合自己 238
第III篇 代碼的形成過程
第13章 崇尚設計——如何創作出優秀的軟體設計 241
13.1 邊設計邊編程 242
13.2 我們要設計什麼 243
13.3 為什麼這么忙亂 244
13.4 良好的軟體設計 245
13.4.1 簡潔 246
13.4.2 優雅 247
13.4.3 模組化 247
13.4.4 良好的接口 248
13.4.5 可擴展性 251
13.4.6 避免重複 251
13.4.7 可移植性 252
13.4.8 符合語言習慣 252
13.4.9 良好地文檔化 253
13.5 如何設計代碼 253
13.5.1 設計方法和過程 254
13.5.2 設計工具 255
13.6 總結 257
13.7 另請參見 258
13.8 思考 258
13.8.1 深入思考 258
13.8.2 結合自己 259
第14章 軟體體系結構——奠定軟體設計的基礎 261
14.1 什麼是軟體體系結構 262
14.1.1 軟體藍圖 262
14.1.2 視圖 263
14.1.3 在何時和何處進行體系結構設計 264
14.1.4 用體系結構來做什麼 265
14.1.5 關於組件和連線 266
14.2 什麼是良好的體系結構 268
14.3 體系結構風格 269
14.3.1 沒有體系結構 269
14.3.2 分層的體系結構 270
14.3.3 管道和過濾器體系結構 271
14.3.4 客戶端/伺服器體系結構 271
14.3.5 基於組件的體系結構 273
14.3.6 框架 274
14.4 總結 275
14.5 另請參見 276
14.6 思考 276
14.6.1 深入思考 276
14.6.2 結合自己 277
第15章改良與革命——代碼是如何成長的 279
15.1 軟體腐爛 281
15.2 警告信號 282
15.3 代碼是如何成長的 284
15.4 相信不可能之事 286
15.5 對此我們可以做些什麼 287
15.5.1 編寫新代碼 287
15.5.2 維護現有代碼 288
15.6 總結 290
15.7 另請參見 290
15.8 思考 291
15.8.1 深入思考 292
15.8.2 結合自己 292
第IV篇 “一群”程式設計師第一部分
第16章 代碼猴子——培養正確的編程態度和方法 295
16.1 各種各樣的猴子 296
16.1.1 賣力工作的程式設計師 297
16.1.2 代碼猴子 298
16.1.3 權威 299
16.1.4 半權威 300
16.1.5 傲慢的天才 300
16.1.6 牛仔 302
16.1.7 規劃者 302
16.1.8 老前輩 303
16.1.9 狂熱者 304
16.1.10 單線條程式設計師 305
16.1.11 拖沓者 306
16.1.12 勉強的團隊領導 306
16.1.13 你 307
16.2 理想的程式設計師 308
16.3 那么該怎么辦 308
16.4 最愚蠢的人 309
16.5 總結 310
16.6 另請參見 310
16.7 行為表格 311
16.8 思考 312
16.8.1 深入思考 312
16.8.2 結合自己 312
第17章 團結就是力量——團隊合作與個人程式設計師 315
17.1 我們的團隊——概覽 316
17.2 團隊組織 318
17.2.1 管理方法 318
17.2.2 責任劃分 318
17.2.3 組織和代碼結構 320
17.3 團隊合作工具 320
17.4 團隊疾病 322
17.4.1 巴別塔 322
17.4.2 獨裁制 324
17.4.3 民主制 325
17.4.4 衛星站 327
17.4.5 大峽谷 329
17.4.6 流沙 330
17.4.7 旅鼠 332
17.5 良好團隊合作的個人技巧和特點 333
17.5.1 溝通 333
17.5.2 謙虛 334
17.5.3 處理衝突 334
17.5.4 學習和適應能力 335
17.5.5 了解你的不足之處 336
17.6 團隊合作原則 336
17.6.1 集體代碼所有制 336
17.6.2 尊重別人的代碼 337
17.6.3 編碼準則 337
17.6.4 定義成功 337
17.6.5 定義責任 338
17.6.6 避免倦怠 338
17.7 團隊的生命周期 339
17.7.1 團隊的創建 339
17.7.2 團隊的成長 341
17.7.3 團隊合作 342
17.7.4 團隊結束 343
17.8 總結 345
17.9 另請參見 346
17.10 行為表格 347
17.11 思考 348
17.11.1 深入思考 348
17.11.2 結合自己 348
第18章 安全措施——原始碼控制與自我控制 349
18.1 我們的責任 350
18.2 原始碼控制 351
18.2.1 修訂控制 352
18.2.2 訪問控制 353
18.2.3 處理代碼庫 354
18.2.4 在代碼樹上創建分支 354
18.2.5 原始碼控制簡史 356
18.3 配置管理 356
18.4 備份 358
18.5 發布原始碼 359
18.6 應該將原始碼放在哪裡 360
18.7 總結 361
18.8 另請參見 362
18.9 思考 363
18.9.1 深入思考 363
18.9.2 結合自己 363
第V篇 開發過程的組成部分第一部分
第19章 注意細節——編寫軟體規範 367
19.1 規範到底是什麼 368
19.2 規範的類型 369
19.2.1 需求規範 371
19.2.2 功能規範 373
19.2.3 系統體系結構規範 373
19.2.4 用戶界面規範 374
19.2.5 設計規範 374
19.2.6 測試規範 375
19.3 規範應當包含哪些內容 376
19.4 規範編寫過程 379
19.5 我們為什麼會不編寫規範 381
19.6 總結 383
19.7 另請參見 383
19.8 思考 384
19.8.1 深入思考 384
19.8.2 結合自己 384
第20章 代碼審查——執行代碼審查 385
20.1 什麼是代碼審查 386
20.2 何時進行審查 387
20.2.1 是否要進行審查 388
20.2.2 審查哪些代碼 389
20.3 執行代碼審查 389
20.3.1 代碼審查會議 390
20.3.2 集成審查 392
20.4 審查你的態度 393
20.4.1 作者的態度 393
20.4.2 審查人員的態度 394
20.5 完美的代碼 395
20.6 代碼審查之外 396
20.7 總結 397
20.8 另請參見 397
20.9 清單 398
20.10 思考 399
20.10.1 深入思考 399
20.10.2 結合自己 399
第21章 時間估計——軟體時間範圍估計的魔術 401
21.1 在黑暗中摸索 402
21.2 為什麼估計這么困難? 403
21.3 壓力之下 405
21.4 實用的估計方法 406
21.5 計畫遊戲 409
21.6 堅持! 412
21.7 總結 415
21.8 另請參見 415
21.9 思考 416
21.9.1 深入思考 416
21.9.2 結合自己 416
第VI篇 從高處鳥瞰
第22章 程式秘方——代碼開發的方法和過程 419
22.1 編程風格 420
22.1.1 結構化編程 421
22.1.2 面向對象的程式設計 422
22.1.3函式式編程423
22.1.4邏輯編程424
22.2 烹飪方法:做什麼與怎樣做 424
22.3 開發過程 425
22.3.1 混亂 426
22.3.2 瀑布模型 427
22.2.3 SSADM和PRINCE 429
22.3.4V模型430
22.3.5 原型設計 430
22.3.6 疊代和增量開發 432
22.3.7 螺旋模型 432
22.3.8 敏捷的方法 433
22.3.9 其他開發過程 434
22.4 已經夠了! 435
22.5 選擇一種過程 436
22.6 總結 437
22.7 另請參見 438
22.8 思考 438
22.8.1 深入思考 438
22.8.2 結合自己 439
第23章 編程領域大觀——不同的編程分支 441
23.1 應用程式編程 442
23.1.1 塑裝軟體 443
23.1.2 定製應用程式 444
23.2 遊戲編程 445
23.3 系統編程 446
23.4 嵌入式編程 447
23.5 分散式編程 450
23.6 網路應用程式編程 451
23.7 企業編程 453
23.8 數字編程 454
23.9 那又怎樣 455
23.10 總結 456
23.11 另請參見 456
23.12 思考 457
23.12.1 深入思考 457
23.12.2 結合自己 457
第24章 下一步呢——結果好就一切都好 459
但下一步該做什麼呢? 460
答案和討論 463
參考書目 559
索引 564
圖書章節
第7章 欲善其事,先利其器——使用工具構建軟體
任何膽敢使用超乎自己力量的裝置,都會身陷危險。
——J.R.R.托爾金(J.R.R. Tolkien)
要想成為一位多產的藝人,你需要有一套順手的工具。水暖工工具箱裡的東西可以幫助他完成任何任務,要不然你就不會在下次家裡的水龍頭漏水時去叨嘮他了。
只是擁有這些工具還不夠,它們的質量也很重要。差勁的工具會讓人對優秀的工匠感到失望。無論你的水暖工有多能幹,如果壓縮閥不好,也會到處都是水。
當然,是你對這些工具的使用使你成為一名傑出的工匠。工具本身什麼也做不成。在電動工具出現之前,木匠們就已經能做出精美的家具了。工具相對而言是基礎的,使用工具的技能才是創造精美物品的關鍵。
編程也是同樣的道理。要把工作做好,你需要得到一套適當工具的支持;這應該是一套讓你充滿信心的工具,你知道如何使用它們,對你所遇到的工作也非常適用。要創造出非凡的代碼,不僅需要有技藝精湛的編程高手,還要有好用的工具和靈活運用這些工具的能力。
這是一個重要的問題。你使用工具的方式可以看出你是否能成為一名真正多產的程式設計師。在極端的情況下,這些工具可以提供決定你的項目成功與否的簡化操作。軟體工廠那不懈的前進步伐,要求你緊緊抓住任何可以幫助你編寫更好的代碼,以及更快和更可靠地編寫代碼的工具。
其他章節會包含一些涉及某種特定工具的內容。本章我們將把軟體工具作為一個整體來討論。編程是一項沒有工具就無法進行的工作。我們日復一日地使用著工具,使用編譯器就像使用開罐器一樣自然,沒有經過太多的思考。如果它運轉正常,就沒有任何問題,但是當它發生了故障(或者你需要開啟一個奇形怪狀的罐頭)時,不管開罐器有多高檔,你都會被卡住。一個簡單便宜但是能用的開罐器要好過一個外表華麗構造複雜但是不能用的裝置。