★作者序★
在1995年版的序言中,我寫道,
如果軟件工程真的是一門工程學科,那么它是對經(jīng)過驗證的原則、技術、語言和工具的智慧的運用,用于有成本效益地創(chuàng)造和維護能夠滿足用戶需求的軟件。本書是有史以來本成冊的軟件工程原則集。原則是關于軟件工程的基本原理、規(guī)則或假設,不管所選的技術、工具或語言是什么,其都有效。
26年后的今天,當我審視這201條原則時,我很高興地宣告,幾乎所有的原則都經(jīng)受住了時間的考驗,就像物理學中的基本原理一樣。
然而,在這26年里,因為軟件造成的問題相當之多。舉幾個例子:
★波音 737 MAX 機動特性增強系統(tǒng)(MCAS)的單點故障導致了兩起空難,共造成 346 人死亡,調(diào)查結果是軟件測試不徹底。
★全球范圍的軟件系統(tǒng)反復被勒索軟件攻擊,表明軟件存在漏洞。
★一個無法預測且未被發(fā)現(xiàn)的溢出錯誤導致人類飛行控制員必須在發(fā)射后立即銷毀阿麗亞娜 5 型運載火箭。
★火星氣候軌道飛行器墜毀在火星上,原因是兩個程序員關于變量的單位出現(xiàn)錯誤溝通:一個認為是磅,另一個認為是牛頓。
當橋梁或建筑物倒塌時,調(diào)查人員會嘗試確定是什么地方出了問題。通常,是因為建筑商未能遵守建筑規(guī)范(即施工期間要遵循的一套規(guī)則或原則),或者檢查員未能找到物理損壞的位置。當軟件失敗時,通常是因為軟件工程組織沒有遵守某個原則。
理解和實踐一門學科的所有原則是否可以預防所有災難?不是。它只會大大降低因你而導致災難的可能性。正如亞歷山大·波普所說,犯錯是人之常情。只有通過犯錯,我們才能學習,并制定新的原則。
在這本書中發(fā)表的大部分原則并非原創(chuàng),很多是從軟件工程從業(yè)者和研究者的著作中摘錄而來的。這些人無私地和我們分享他們的經(jīng)驗、想法和智慧。我并不認為這201個原則是相互獨立的。不像Boehm提出的7個基本軟件工程原則,本書中的一些原則的組合可能蘊涵另一個原則。但我也不認為這201個原則中的某兩個或某幾個原則是100% 兼容的。俗話所說的,距離產(chǎn)生美和眼不見,心不煩都是真理,每個原則都可以應用在我們的生活中,但是它們卻不能同時用來證明同一個決定是正確的。本書中包含的原則都是有效的,它們都能夠用來提升軟件工程的水平,但也許并不能將某些組合應用到同一個項目中。
本版中的原則與1995版中的原則相同。但是,你可能會對我的想法感興趣,哪些仍然是正確的,哪些是我懷疑的。以下是我的想法:
對于第 2 章中介紹的一般原則,全部依然有效。一些額外說明如下。
★在原則 23~25 中,CASE這個詞已經(jīng)不流行了。今天,主要的軟件開發(fā)工具支持問題跟蹤、版本控制、虛擬機模擬、項目管理和調(diào)試。
★ 對于原則 28,我必須承認,在過去 26 年里,據(jù)我所知,沒有一個為我工作過的軟件工程師使用過形式化方法本身,盡管其中很多人還擁有高等數(shù)學學位,也就是說,他們在本質(zhì)上,是知道如何以形式化的方式思考的。
對于第 3 章中介紹的需求工程原則,全部依然有效。一些額外說明如下。
★對于原則 40、41、43、45、47、48、49 和 54,在過去 26 年的大部分時間里,我一直致力于創(chuàng)業(yè),在這種環(huán)境下,向客戶提供一系列不斷增大的小可行產(chǎn)品(MVP)以獲取他們的反饋至關重要。我們只是在問題跟蹤工具中以自然語言維護我們的需求,我們可以輕松地用優(yōu)先級、目標版本、狀態(tài)和注解對它們進行注釋。當然,這正是原則 60 所體現(xiàn)的精神。
對于第 4 章中介紹的設計原則,全部依然有效。一些額外說明如下。
★對于原則 73,如今耦合和內(nèi)聚變得不那么重要,已經(jīng)被重用所取代。今天,我們通過從大量經(jīng)過驗證的組件庫中選取許多組件來構建系統(tǒng),并在必要時進行定制開發(fā)。庫所依賴的框架傾向于鼓勵弱耦合和強內(nèi)聚,但我們不再需要考慮它了。
★ 原則 76 和 84 可能是所有原則中重要的原則。當然,我們在過去26年見證了框架的出現(xiàn),它使軟件重用變得更加容易。事實上,不再稱之為重用,我們就簡稱其為軟件開發(fā)。
★隨著硬件變得更快、更便宜,原則 79 變得越來越不重要。
★原則 80,如果實施更正,可能已經(jīng)避免了阿麗亞娜 5 型火箭的災難。
對于第 5 章中介紹的編碼原則,全部依然有效。一些額外說明如下。
★對于原則 94,我認為現(xiàn)代軟件工程師不需要再擔心這個了。
★對于原則 96,這仍然是我的愛之一。我一直在實踐它,我的軟件工程師同事認為我瘋了。
對于第 6 章中介紹的測試原則,全部依然有效。一些額外說明如下。
★對于原則 120,謹以此向我的朋友湯姆·麥克凱布致以崇高的敬意,我認為他的指標已經(jīng)不再有用。我知道沒有人再使用它了。對不起,湯姆。
★ 對于原則 124,所有現(xiàn)代測試工具都會自動執(zhí)行此操作。
對于第 7 章中介紹的管理原則,全部依然有效。一些額外說明如下。
★對于原則 129、131、132、133、134、135、137、138、140、142 和 147,如果你不相信這些,請不要成為經(jīng)理。
★ 對于原則 168,對當今的大多數(shù)應用程序來說不是一個真正的問題。
對于第 8 章中介紹的產(chǎn)品保證原則,全部依然有效。一些額外說明:
★我近托運了一輛自行車,幾乎橫跨了整個國家,當收到時,貨物箱子損壞而且很多零件不見了。我聯(lián)系制造商購買缺少的零件,他們告訴我,每輛自行車都不同,雖然我有型號,但每輛自行車的每個實例都是不同的。不僅如此,他們也沒有記錄每輛運輸?shù)淖孕熊嚱M裝了哪些零件,因此他們不可能將丟失的零件寄給我。我很震驚。軟件配置管理(如今,通常稱為版本控制)應該跟蹤每個組件的每個版本,以及組件版本的哪些組合構成了可行的系統(tǒng),以及哪些客戶擁有哪些可行的版本。我認為這應該是一個新的原則。
★對于原則 176 和 177,可能不再那么重要了。
對于第 9 章中介紹的演變原則,全部依然有效。
Alan M. Davis
2021.9
★譯者序★
我不是譯者,僅是一名校對者。大家讓我來寫這篇譯者序,盛情難卻,無法推脫。本書英文版是我于2017年至2020年在百度舉辦代碼的藝術訓練營時使用的教材。這本書的內(nèi)容深受訓練營學員的好評。由于之前沒有中文版,對于部分英文基礎不太好的同學來說,閱讀有些困難。在2019年年底,十多名代碼的藝術訓練營的畢業(yè)生自發(fā)組織起來,開始了對此書的翻譯工作。我從2020年5月初開始校對工作,完成全書的校對,我花費了80~100小時。由此推斷,負責翻譯的同學花費了數(shù)倍于此的時間。非常感謝這些同學的無私付出!
初識本書英文版是在二十多年前。當時我還在清華大學讀書,在老師的指導下做一個有一定規(guī)模的軟件研發(fā)項目,在項目的研發(fā)過程中,遇到了不少軟件工程方面的問題。于是在那一年,我閱讀了大約十本軟件工程方面的圖書,包括Code Complete(《代碼大全》)、Rapid Development、Programming Pearls(《編程珠璣》),等等。本書是我當時在清華大學圖書館里發(fā)現(xiàn)的寶貝。我必須說,此書對我的影響非常大,很多我現(xiàn)在經(jīng)常提起的軟件工程原則,都源于對這本書的閱讀。
2006年我離開清華大學,到目前為止已經(jīng)在工業(yè)界工作了十多年,先后就職于多家公司。我發(fā)現(xiàn),雖然我們的軟件研發(fā)規(guī)模和二十多年前相比有了很大的發(fā)展,但是在軟件研發(fā)理念方面的進步還是太慢了。有太多的軟件從業(yè)者,雖然已經(jīng)工作多年,但對軟件研發(fā)的基本理念和原則了解得還是不夠多。根據(jù)我的多次調(diào)查,閱讀超過兩本真正的軟件工程圖書的人都非常少。很多軟件工程師,仍然使用非常低效甚至是錯誤的方法在工作!
于是在2015年,我在百度開辦了代碼的藝術面授課程,其中就重點推薦了本書的英文版。而在2017年做代碼的藝術訓練營的時候,這本書就成了指定教材。為什么要選擇這本書?因為它對軟件工程的內(nèi)容覆蓋全面,且篇幅短小。對于一個短期培訓班來說,如果選擇類似《代碼大全》這樣的圖書,閱讀所需要的時間就有些太多了。在這種情況下,本書的英文版是一個性價比更高的選擇。另外,我常常感覺,對于一個軟件工程師,具備正確的意識比掌握具體的知識更重要。如果有正確的意識,即使不記得具體的知識點,也可以在需要的時候查閱相關資料,而反過來則不是這樣的。
必須要說的是,本書的英文版寫于1995年,距今已經(jīng)有26年。這也是很多人擔心的地方計算機技術發(fā)展得如此之快,這本書是不是已經(jīng)過時了?但是,正如我在代碼的藝術課程中對知識方法精神三者所做的對比,方法的變化速度遠遠慢于知識。尤其是在本次校對過程中,我驚奇地發(fā)現(xiàn),書中真的可以說是過時的原則不足5個!是軟件研發(fā)的方法變化太慢,還是書的內(nèi)容太深刻?我想兩者兼而有之。在此,我必須要對本書的作者Alan M. Davis致敬,并對書中所有原則的貢獻者和歷史上所有軟件工程領域的大師們致敬!
在此,我要隆重介紹翻譯本書的百度的同學們,他們是:葉王、馬學翔、吳斌、王冰清、楊光、曾浩浩、李殿斌、甘璐、李子昂、肖遠昊、賈儒、王瑩、張苗、李雙婕、榮文升。另外,經(jīng)大家商定,將本書因翻譯出版獲得的稿酬全都捐贈給公益事業(yè)。
后,所有閱讀本書的軟件工程師和所有準備從事軟件研發(fā)的同學們,我祝愿本書能助你們?nèi)〉酶蟮某晒Γ?/p>
章淼 博士 百度BFE團隊技術負責人、百度代碼規(guī)范委員會主席
2021年6月14日寫于百度
★第1章 引言★
★第2章 一般原則★
原則1 質(zhì)量
原則2 質(zhì)量在每個人眼中都不同
原則3 開發(fā)效率和質(zhì)量密不可分
原則4 高質(zhì)量軟件是可以實現(xiàn)的
原則5 不要試圖通過改進軟件實現(xiàn)高質(zhì)量
原則6 低可靠性比低效率更糟糕
原則7 盡早把產(chǎn)品交給客戶
原則8 與客戶/用戶溝通
原則9 促使開發(fā)者與客戶的目標一致
原則10 做好拋棄的準備
原則11 開發(fā)正確的原型
原則12 構建合適功能的原型
原則13 要快速地開發(fā)一次性原型
原則14 漸進地擴展系統(tǒng)
原則15 看到越多,需要越多
原則16 開發(fā)過程中的變化是不可避免的
原則17 只要可能,購買而非開發(fā)
原則18 讓軟件只需簡短的用戶手冊
原則19 每個復雜問題都有一個解決方案
原則20 記錄你的假設
原則21 不同的階段,使用不同的語言
原則22 技術優(yōu)先于工具
原則23 使用工具,但要務實
原則24 把工具交給優(yōu)秀的工程師
原則25 CASE工具是昂貴的
原則26 知道何時和知道如何同樣重要
原則27 實現(xiàn)目標就停止
原則28 了解形式化方法
原則29 和組織榮辱與共
原則30 跟風要小心
原則31 不要忽視技術
原則32 使用文檔標準
原則33 文檔要有術語表
原則34 軟件文檔都要有索引
原則35 對相同的概念用相同的名字
原則36 研究再轉(zhuǎn)化,不可行
原則37 要承擔責任
★第3章 需求工程原則★
原則38 低質(zhì)量的需求分析,導致低質(zhì)量的成本估算
原則39 先確定問題,再寫需求
原則40 立即確定需求
原則41 立即修復需求規(guī)格說明中的錯誤
原則42 原型可降低選擇用戶界面的風險
原則43 記錄需求為什么被引入
原則44 確定子集
原則45 評審需求
原則46 避免在需求分析時進行系統(tǒng)設計
原則47 使用正確的方法
原則48 使用多角度的需求視圖
原則49 合理地組織需求
原則50 給需求排列優(yōu)先級
原則51 書寫要簡潔
原則52 給每個需求單獨編號
原則53 減少需求中的歧義
原則54 對自然語言輔助增強,而非替換
原則55 在更形式化的模型前,先寫自然語言
原則56 保持需求規(guī)格說明的可讀性
原則57 明確規(guī)定可靠性
原則58 應明確環(huán)境超出預期時的系統(tǒng)行為
原則59 自毀的待定項
原則60 將需求保存到數(shù)據(jù)庫
★第4章 設計原則★
原則61 從需求到設計的轉(zhuǎn)換并不容易
原則62 將設計追溯至需求
原則63 評估備選方案
原則64 沒有文檔的設計不是設計
原則65 封裝
原則66 不要重復造輪子
原則67 保持簡單
原則68 避免大量的特殊案例
原則69 縮小智力距離
原則70 將設計置于知識控制之下
原則71 保持概念一致
原則72 概念性錯誤比語法錯誤更嚴重
原則73 使用耦合和內(nèi)聚
原則74 為變化而設計
原則75 為維護而設計
原則76 為防備出現(xiàn)錯誤而設計
原則77 在軟件中植入通用性
原則78 在軟件中植入靈活性
原則79 使用高效的算法
原則80 模塊規(guī)格說明只提供用戶需要的所有信息
原則81 設計是多維的
原則82 優(yōu)秀的設計出自優(yōu)秀的設計師
原則83 理解你的應用場景
原則84 無須太多投資,即可實現(xiàn)復用
原則85 錯進錯出是不正確的
原則86 軟件可靠性可以通過冗余來實現(xiàn)
★第5章 編碼原則★
原則87 避免使用特殊技巧
原則88 避免使用全局變量
原則89 編寫可自上而下閱讀的程序
原則90 避免副作用
原則91 使用有意義的命名
原則92 程序首先是寫給人看的
原則93 使用的數(shù)據(jù)結構
原則94 先確保正確,再提升性能
原則95 在寫完代碼之前寫注釋
原則96 先寫文檔后寫代碼
原則97 手動運行每個組件
原則98 代碼審查
原則99 你可以使用非結構化的語言
原則100 結構化的代碼未必是好的代碼
原則101 不要嵌套太深
原則102 使用合適的語言
原則103 編程語言不是借口
原則104 編程語言的知識沒那么重要
原則105 格式化你的代碼
原則106 不要太早編碼
★第6章 測試原則★
原則107 依據(jù)需求跟蹤測試
原則108 在測試之前早做測試計劃
原則109 不要測試自己開發(fā)的軟件
原則110 不要為自己的軟件做測試計劃
原則111 測試只能揭示缺陷的存在
原則112 雖然大量的錯誤可證明軟件毫無價值,但是零錯誤并不能說明軟件的價值
原則113 成功的測試應發(fā)現(xiàn)錯誤
原則114 半數(shù)的錯誤出現(xiàn)在15%的模塊中
原則115 使用黑盒測試和白盒測試
原則116 測試用例應包含期望的結果
原則117 測試不正確的輸入
原則118 壓力測試必不可少
原則119 大爆炸理論不適用
原則120 使用 McCabe 復雜度指標
原則121 使用有效的測試完成度標準
原則122 達成有效的測試覆蓋
原則123 不要在單元測試之前集成
原則124 測量你的軟件
原則125 分析錯誤的原因
原則126 對錯不對人
★第7章 管理原則★
原則127 好的管理比好的技術更重要
原則128 使用恰當?shù)姆椒?/p>
原則129 不要相信你讀到的一切
原則130 理解客戶的優(yōu)先級
原則131 人是成功的關鍵
原則132 幾個好手要強過很多生手
原則133 傾聽你的員工
原則134 信任你的員工
原則135 期望優(yōu)秀
原則136 溝通技巧是必要的
原則137 端茶送水
原則138 人們的動機是不同的
原則139 讓辦公室保持安靜
原則140 人和時間是不可互換的
原則141 軟件工程師之間存在巨大的差異
原則142 你可以優(yōu)化任何你想要優(yōu)化的
原則143 隱蔽地收集數(shù)據(jù)
原則144 每行代碼的成本是沒用的
原則145 衡量開發(fā)效率沒有完美的方法
原則146 剪裁成本估算方法
原則147 不要設定不切實際的截止時間
原則148 避免不可能
原則149 評估之前先要了解
原則150 收集生產(chǎn)力數(shù)據(jù)
原則151 不要忘記團隊效率
原則152 LOC/PM與語言無關
原則153 相信排期
原則154 精確的成本估算并不是萬無一失的
原則155 定期重新評估排期
原則156 輕微的低估不總是壞事
原則157 分配合適的資源
原則158 制訂詳細的項目計劃
原則159 及時更新你的計劃
原則160 避免駐波
原則161 知曉十大風險
原則162 預先了解風險
原則163 使用適當?shù)牧鞒棠P?/p>
原則164 方法無法挽救你
原則165 沒有奇跡般提升效率的秘密
原則166 了解進度的含義
原則167 按差異管理
原則168 不要過度使用你的硬件
原則169 對硬件的演化要樂觀
原則170 對軟件的進化要悲觀
原則171 認為災難是不可能的想法往往導致災難
原則172 做項目總結
★第8章 產(chǎn)品保證原則★
原則173 產(chǎn)品保證并不是奢侈品
原則174 盡早建立軟件配置管理過程
原則175 使軟件配置管理適應軟件過程
原則176 組織SCM獨立于項目管理
原則177 輪換人員到產(chǎn)品保證組織
原則178 給所有中間產(chǎn)品一個名稱和版本
原則179 控制基準
原則180 保存所有內(nèi)容
原則181 跟蹤每一個變更
原則182 不要繞過變更控制
原則183 對變更請求進行分級和排期
原則184 在大型開發(fā)項目中使用確認和驗證(V&V)
★第9章 演變原則★
原則185 軟件會持續(xù)變化
原則186 軟件的熵增加
原則187 如果沒有壞,就不要修理它
原則188 解決問題,而不是癥狀
原則189 先變更需求
原則190 發(fā)布之前的錯誤也會在發(fā)布之后出現(xiàn)
原則191 一個程序越老,維護起來越困難
原則192 語言影響可維護性
原則193 有時重新開始會更好
原則194 首先翻新差的
原則195 維護階段比開發(fā)階段產(chǎn)生的錯誤更多
原則196 每次變更后都要進行回歸測試
原則197 變更很容易的想法,會使變更更容易出錯
原則198 對非結構化代碼進行結構化改造,并不一定會使它更好
原則199 在優(yōu)化前先進行性能分析
原則200 保持熟悉
原則201 系統(tǒng)的存在促進了演變
★參考資料索引★
★術語索引★