軟件質(zhì)量,不但依賴架構(gòu)和項(xiàng)目管理,而且與代碼質(zhì)量緊密相關(guān)。這一點(diǎn),無論是敏捷開發(fā)流派還是傳統(tǒng)開發(fā)流派,都不得不承認(rèn)。
本書提出一種觀點(diǎn):代碼質(zhì)量與其整潔度成正比。干凈的代碼,既在質(zhì)量上較為可靠,也為后期維護(hù)、升級(jí)奠定了良好基礎(chǔ)。作為編程領(lǐng)域的佼佼者,本書作者給出了一系列行之有效的整潔代碼操作實(shí)踐。這些實(shí)踐在本書中體現(xiàn)為一條條規(guī)則(或稱“啟示”),并輔以來自實(shí)際項(xiàng)目的正、反兩面的范例。只要遵循這些規(guī)則,就能編寫出干凈的代碼,從而有效提升代碼質(zhì)量。
本書閱讀對(duì)象為有志于改善代碼質(zhì)量的程序員和技術(shù)經(jīng)理。書中介紹的規(guī)則均來自作者多年的實(shí)踐經(jīng)驗(yàn),涵蓋從命名到重構(gòu)的多個(gè)編程方面,雖為一家之言,然誠(chéng)有可資借鑒的價(jià)值。
1.“閱讀這本書有兩種原因:第一,你是個(gè)程序員;第二,你想成為更好的程序員。很好,IT行業(yè)需要更好的程序員!”——羅伯特·C. 馬。≧obert C. Martin)
2. 提出"代碼質(zhì)量與其整潔度成正比",經(jīng)數(shù)百萬程序員實(shí)踐驗(yàn)證與推崇;強(qiáng)調(diào)"以簡(jiǎn)單又直接的方式描繪代碼的功能",奠定重構(gòu)和調(diào)優(yōu)的基礎(chǔ);闡述設(shè)計(jì)原則、方法與實(shí)踐案例,助力頻繁而快速地發(fā)布高質(zhì)量代碼。
3. C++首席專家&作家James O. Coplien作序推薦,豆瓣評(píng)分8.6分,被譽(yù)為"程序員童子軍規(guī)則",軟件開發(fā)不可不讀的經(jīng)典著作。
盡管糟糕的代碼也能運(yùn)行,但如果代碼不整潔,會(huì)使整個(gè)開發(fā)團(tuán)隊(duì)泥足深陷,寫得不好的代碼每年都要耗費(fèi)難以計(jì)數(shù)的時(shí)間和資源。但是,這種情況并非無法避免。
著名軟件專家羅伯特·C. 馬。≧obert C. Martin) 在本書中為你呈現(xiàn)了革命性的視野。他攜同Object Mentor公司的同事,從他們有關(guān)整潔代碼的高效敏捷實(shí)踐中提煉出軟件技藝的價(jià)值觀,以饗讀者,讓你成為更優(yōu)秀的程序員——只要你著手研讀本書。
閱讀本書需要你做些什么呢?你將閱讀代碼——大量代碼。本書會(huì)促使你思考何謂正確的代碼,何謂錯(cuò)誤的代碼。更重要的是,本書將促使你重新評(píng)估自己的專業(yè)價(jià)值觀,以及對(duì)自己技藝的承諾。
書中的具體內(nèi)容包括:
·好代碼和糟糕的代碼之間的區(qū)別;
·如何編寫好代碼,如何將糟糕的代碼轉(zhuǎn)化為好代碼;
·如何創(chuàng)建好名稱、好函數(shù)、好對(duì)象和好類;
·如何格式化代碼以實(shí)現(xiàn)其可讀性的最大化;
·如何在不妨礙代碼邏輯的前提下充分實(shí)現(xiàn)錯(cuò)誤處理;
·如何進(jìn)行單元測(cè)試和測(cè)試驅(qū)動(dòng)開發(fā)。
[美] 羅伯特·C. 馬丁(Robert C. Martin):
軟件開發(fā)大師,設(shè)計(jì)模式和敏捷開發(fā)先驅(qū),敏捷聯(lián)盟首任主席,C++ Report前主編,被后輩程序員尊稱為“Bob大叔”。20世紀(jì)70年代初成為職業(yè)程序員,后創(chuàng)辦Object Mentor公司并任總裁。Martin還是一名多產(chǎn)的作家,至今已發(fā)表數(shù)百篇文章、論文和博客文章。除本書外,還著有《代碼整潔之道:程序員的職業(yè)素養(yǎng)》《敏捷軟件開發(fā):原則、模式和實(shí)踐》《UML:Java程序員指南》等。
Chapter 1: Clean Code / 整潔代碼 1
There Will Be Code / 要有代碼 2
Bad Code / 糟糕的代碼 3
The Total Cost of Owning a Mess / 混亂的代價(jià) 4
Schools of Thought / 思想流派 12
We Are Authors / 我們是作者 13
The Boy Scout Rule / 童子軍軍規(guī) 14
Prequel and Principles / 前傳與原則 15
Conclusion / 小結(jié) 15
Bibliography / 文獻(xiàn) 15
Chapter 2: Meaningful Names / 有意義的命名 17
Introduction / 介紹 17
Use Intention-Revealing Names / 名副其實(shí) 18
Avoid Disinformation / 避免誤導(dǎo) 19
Make Meaningful Distinctions / 做有意義的區(qū)分 20
Use Pronounceable Names / 使用讀得出來的名稱 21
Use Searchable Names / 使用可搜索的名稱 22
Avoid Encodings / 避免使用編碼 23
Avoid Mental Mapping / 避免思維映射 25
Class Names / 類名 25
Method Names / 方法名 25
Don’t Be Cute / 別抖機(jī)靈 26
Pick One Word per Concept / 每個(gè)概念對(duì)應(yīng)一個(gè)詞 26
Don’t Pun / 別用雙關(guān)語 26
Use Solution Domain Names / 使用解決方案領(lǐng)域名稱 27
Use Problem Domain Names / 使用源自所涉問題領(lǐng)域的名稱 27
Add Meaningful Context / 添加有意義的語境 27
Don’t Add Gratuitous Context / 不要添加沒用的語境 29
Final Words / 最后的話 30
Chapter 3: Functions / 函數(shù) 31
Small! / 短小 34
Do One Thing 只做一件事 35
One Level of Abstraction per Function / 每個(gè)函數(shù)一個(gè)抽象層級(jí) 36
Switch Statements / switch 語句 37
Use Descriptive Names / 使用具有描述性的名稱 39
Function Arguments / 函數(shù)參數(shù) 40
Have No Side Effects / 無副作用 44
Command Query Separation / 分隔指令與詢問 45
Prefer Exceptions to Returning Error Codes / 使用異常替代返回錯(cuò)誤碼 46
Don’t Repeat Yourself / 別重復(fù)自己 48
Structured Programming / 結(jié)構(gòu)化編程 48
How Do You Write Functions Like This / 如何寫出這樣的函數(shù) 49
Conclusion / 小結(jié) 49
SetupTeardownIncluder / SetupTeardownIncluder 程序 50
Bibliography / 文獻(xiàn) 52
Chapter 4: Comments / 注釋 53
Comments Do Not Make Up for Bad Code /注釋不能美化糟糕的代碼 55
Explain Yourself in Code / 用代碼來闡述 55
Good Comments / 好注釋 55
Bad Comments / 壞注釋 59
Bibliography / 文獻(xiàn) 74
Chapter 5: Formatting/ 75
The Purpose of Formatting / 格式的目的 76
Vertical Formatting / 垂直格式 76
Horizontal Formatting / 橫向格式 85
Team Rules / 團(tuán)隊(duì)規(guī)則 90
Uncle Bob’s Formatting Rules / “鮑勃大叔”的格式規(guī)則 90
Chapter 6: Objects and Data Structures / 對(duì)象和數(shù)據(jù)結(jié)構(gòu) 93
Data Abstraction / 數(shù)據(jù)抽象 93
Data/Object Anti-Symmetry / 數(shù)據(jù)、對(duì)象的反對(duì)稱性 95
The Law of Demeter / 得墨忒耳律 97
Data Transfer Objects / 數(shù)據(jù)傳送對(duì)象 100
Conclusion / 小結(jié) 101
Bibliography / 文獻(xiàn) 101
Chapter 7: Error Handling / 錯(cuò)誤處理 103
Use Exceptions Rather Than Return Codes / 使用異常而非返回碼 104
Write Your Try-Catch-Finally Statement First /
先寫try-catch-finally 語句 105
Use Unchecked Exceptions / 使用未檢異常 106
Provide Context with Exceptions / 給出異常發(fā)生的環(huán)境說明 107
Define Exception Classes in Terms of a Caller’s Needs /
依調(diào)用者需要定義異常類 107
Define the Normal Flow / 定義常規(guī)流程 109
Don’t Return Null / 別返回null 值 110
Don’t Pass Null / 別傳遞null 值 111
Conclusion / 小結(jié) 112
Bibliography / 文獻(xiàn) 112
Chapter 8: Boundaries / 邊界 113
Using Third-Party Code / 使用第三方代碼 114
Exploring and Learning Boundaries / 瀏覽和學(xué)習(xí)邊界 116
Learning log4j / 學(xué)習(xí)log4j 116
Learning Tests Are Better Than Free /
學(xué)習(xí)性測(cè)試的好處不只是免費(fèi) 118
Using Code That Does Not Yet Exist / 使用尚不存在的代碼 118
Clean Boundaries / 整潔的邊界 120
Bibliography / 文獻(xiàn) 120
Chapter 9: Unit Tests / 單元測(cè)試 121
The Three Laws of TDD / TDD 三定律 122
Keeping Tests Clean / 保持測(cè)試整潔 123
Clean Tests / 整潔的測(cè)試 124
One Assert per Test / 每個(gè)測(cè)試一個(gè)斷言 130
F.I.R.S.T. 132
Conclusion / 小結(jié) 133
Bibliography / 文獻(xiàn) 133
Chapter 10: Classes / 類 135
Class Organization / 類的組織 136
Classes Should Be Small! / 類應(yīng)該短小 136
Organizing for Change / 為了修改而組織 147
Bibliography / 文獻(xiàn) 151
Chapter 11: Systems / 系統(tǒng) 153
How Would You Build a City / 如何建造一個(gè)城市 154
Separate Constructing a System from Using It /
將系統(tǒng)的構(gòu)造與使用分開 154
Scaling Up / 擴(kuò)容 157
Java Proxies / Java 代理 161
Pure Java AOP Frameworks / 純Java AOP 框架 163
AspectJ Aspects / AspectJ 的方面 166
Test Drive the System Architecture / 測(cè)試驅(qū)動(dòng)系統(tǒng)架構(gòu) 166
Optimize Decision Making / 優(yōu)化決策 167
Use Standards Wisely, When They Add Demonstrable Value /
明智使用添加了可論證價(jià)值的標(biāo)準(zhǔn) 168
Systems Need Domain-Specific Languages /
系統(tǒng)需要領(lǐng)域特定語言 168
Conclusion / 小結(jié) 169
Bibliography / 文獻(xiàn) 169
Chapter 12: Emergence / 迭進(jìn) 171
Getting Clean via Emergent Design / 通過迭進(jìn)設(shè)計(jì)達(dá)到整潔目的 171
Simple Design Rule 1: Runs All the Tests /
簡(jiǎn)單設(shè)計(jì)規(guī)則1:運(yùn)行所有測(cè)試 172
Simple Design Rules 2–4: Refactoring / 簡(jiǎn)單設(shè)計(jì)規(guī)則2~4:重構(gòu) 172
No Duplication / 不可重復(fù) 173
Expressive / 表達(dá)力 175
Minimal Classes and Methods / 盡可能少的類和方法 176
Conclusion / 小結(jié) 176
Bibliography / 文獻(xiàn) 176
Chapter 13: Concurrency / 并發(fā)編程 177
Why Concurrency / 為什么要并發(fā) 178
Challenges / 挑戰(zhàn) 180
Concurrency Defense Principles / 并發(fā)防御原則 180
Know Your Library / 了解Java 庫(kù) 182
Know Your Execution Models / 了解執(zhí)行模型 183
Beware Dependencies Between Synchronized Methods /
警惕同步方法之間的依賴 185
Keep Synchronized Sections Small / 保持同步區(qū)域微小 185
Writing Correct Shut-Down Code Is Hard /
很難編寫正確的關(guān)閉代碼 186
Testing Threaded Code / 測(cè)試線程代碼 186
Conclusion / 小結(jié) 190
Bibliography / 文獻(xiàn) 191
Chapter 14: Successive Refinement / 逐步改進(jìn) 193
Args Implementation / Args 的實(shí)現(xiàn) 194
Args: The Rough Draft / Args:草稿 201
String Arguments / 字符串類型參數(shù) 214
Conclusion / 小結(jié) 250
Chapter 15: JUnit Internals / JUnit 內(nèi)幕 251
The JUnit Framework / JUnit 框架 252
Conclusion / 小結(jié) 265
Chapter 16: Refactoring SerialDate / 重構(gòu)SerialDate 267
First, Make It Work / 首先,讓它能工作 268
Then Make It Right / 讓它做對(duì) 270
Conclusion / 小結(jié) 284
Bibliography / 文獻(xiàn) 284
Chapter 17: Smells and Heuristics / 味道與啟發(fā) 285
Comments / 注釋 286
Environment / 環(huán)境 287
Functions / 函數(shù) 288
General / 一般性問題 288
Java 307
Names / 名稱 309
Tests / 測(cè)試 313
Conclusion / 小結(jié) 314
Bibliography / 文獻(xiàn) 315
Appendix A: Concurrency II / 并發(fā)編程II 317
Appendix B: org.jfree.date.SerialDate 349
Appendix C: Cross References of Heuristics / 啟發(fā)式交叉參考 409
Epilogue / 結(jié)束語 411