使用現(xiàn)代C 編寫(xiě)可維護(hù)、可擴(kuò)展和持久的軟件。對(duì)于每一個(gè)對(duì)好的C 代碼感興趣的開(kāi)發(fā)人員、軟件架構(gòu)師或團(tuán)隊(duì)領(lǐng)導(dǎo)來(lái)說(shuō),這本書(shū)都是必須的,因此也想節(jié)省開(kāi)發(fā)成本。如果你想自學(xué)編寫(xiě)整潔C 代碼,本書(shū)正是你所需要的。編寫(xiě)它是為了幫助所有級(jí)別的C 開(kāi)發(fā)人員,并通過(guò)示例展示如何編寫(xiě)可理解的、靈活的、可維護(hù)的和高效的C 代碼。即使是經(jīng)驗(yàn)豐富的C 開(kāi)發(fā)人員,在本書(shū)中也會(huì)發(fā)現(xiàn)一些有用的信息和數(shù)據(jù)。
斯蒂芬·羅斯(Stephan Roth)是德國(guó)漢堡一家咨詢公司的系統(tǒng)和軟件工程導(dǎo)師、顧問(wèn)和培訓(xùn)師。在此之前,他在無(wú)線電偵察和通信情報(bào)系統(tǒng)領(lǐng)域做了多年的軟件開(kāi)發(fā)工程師、軟件架構(gòu)師和系統(tǒng)工程師。Stephan還是一位的演說(shuō)家及作家,目前已出版多本專(zhuān)業(yè)書(shū)籍。此外,他還是一個(gè)堅(jiān)定的軟件工藝運(yùn)動(dòng)支持者,關(guān)注于簡(jiǎn)潔代碼開(kāi)發(fā)的規(guī)范制定及實(shí)踐。
譯者序
關(guān)于作者
關(guān)于技術(shù)審校
致謝
第1章 簡(jiǎn)介1
1.1 軟件熵2
1.2 整潔的代碼4
1.3 為什么使用C 4
1.4 C 11新時(shí)代的開(kāi)始5
1.5 適合本書(shū)的讀者5
1.6 本書(shū)使用的約定6
1.6.1 擴(kuò)展閱讀6
1.6.2 說(shuō)明、提示和警告6
1.6.3 示例代碼7
1.6.4 編碼風(fēng)格7
1.7 相關(guān)網(wǎng)站和代碼庫(kù)7
1.8 UML圖8
第2章 構(gòu)建安全體系9
2.1 測(cè)試的必要性9
2.2 測(cè)試入門(mén)11
2.3 單元測(cè)試13
2.4 關(guān)于QA15
2.5 良好的單元測(cè)試原則16
2.5.1 單元測(cè)試的代碼的質(zhì)量16
2.5.2 單元測(cè)試的命名16
2.5.3 單元測(cè)試的獨(dú)立性17
2.5.4 一個(gè)測(cè)試一個(gè)斷言18
2.5.5 單元測(cè)試環(huán)境的獨(dú)立初始化19
2.5.6 不對(duì)getters和setters做單元測(cè)試19
2.5.7 不對(duì)第三方代碼做單元測(cè)試20
2.5.8 不對(duì)外部系統(tǒng)做單元測(cè)試20
2.5.9 如何處理數(shù)據(jù)庫(kù)的訪問(wèn)20
2.5.10 不要混淆測(cè)試代碼和產(chǎn)品代碼21
2.5.11 測(cè)試必須快速執(zhí)行23
2.5.12 測(cè)試替身24
第3章 原則27
3.1 什么是原則27
3.2 保持簡(jiǎn)單和直接原則(KISS)28
3.3 不需要原則(YAGNI)29
3.4 避免復(fù)制原則(DRY)29
3.5 信息隱藏原則30
3.6 高內(nèi)聚原則33
3.7 松耦合原則35
3.8 小心優(yōu)化原則38
3.9 最少驚訝原則(PLA)39
3.10 童子軍原則39
第4章 C 代碼整潔的基本規(guī)范41
4.1 良好的命名42
4.1.1 名稱應(yīng)該自解釋43
4.1.2 使用域中的名稱45
4.1.3 選擇適當(dāng)抽象層次的名稱45
4.1.4 避免冗余的名稱46
4.1.5 避免晦澀難懂的縮寫(xiě)47
4.1.6 避免匈牙利命名和命名前綴47
4.1.7 避免相同的名稱用于不同的目的48
4.2 注釋49
4.2.1 讓寫(xiě)代碼像講故事一樣49
4.2.2 不要為易懂的代碼寫(xiě)注釋50
4.2.3 不要通過(guò)注釋禁用代碼50
4.2.4 不要寫(xiě)塊注釋51
4.2.5 特殊情況的注釋是有用的53
4.3 函數(shù)56
4.3.1 只做一件事情59
4.3.2 讓函數(shù)盡可能小59
4.3.3 函數(shù)命名61
4.3.4 使用容易理解的名稱61
4.3.5 函數(shù)的參數(shù)和返回值62
4.4 C 工程中的C風(fēng)格代碼72
4.4.1 使用C 的string和stream替代C風(fēng)格的char*73
4.4.2 避免使用printf()、sprintf()和gets()等74
4.4.3 使用標(biāo)準(zhǔn)庫(kù)的容器而不是C風(fēng)格的數(shù)組77
4.4.4 用C 類(lèi)型轉(zhuǎn)換代替C風(fēng)格的強(qiáng)制轉(zhuǎn)換80
4.4.5 避免使用宏81
第5章 現(xiàn)代C 的高級(jí)概念83
5.1 資源管理84
5.1.1 資源申請(qǐng)即初始化85
5.1.2 智能指針86
5.1.3 避免顯式的new和delete92
5.1.4 管理特有資源92
5.2 Move語(yǔ)義94
5.2.1 什么是Move語(yǔ)義94
5.2.2 左值和右值的關(guān)系95
5.2.3 右值引用96
5.2.4 不要濫用Move97
5.2.5 零原則98
5.3 編譯器是你的搭檔102
5.3.1 自動(dòng)類(lèi)型推導(dǎo)102
5.3.2 編譯時(shí)計(jì)算105
5.3.3 模板變量107
5.4 不允許未定義的行為108
5.5 Type-Rich編程110
5.6 了解你使用的庫(kù)116
5.6.1 熟練使用
116
5.6.2 熟練使用Boost121
5.6.3 應(yīng)該了解的一些庫(kù)121
5.7 恰當(dāng)?shù)漠惓:湾e(cuò)誤處理機(jī)制122
5.7.1 防患于未然123
5.7.2 異常即異常字面上的意思126
5.7.3 如果不能恢復(fù)則盡快退出128
5.7.4 用戶自定義異常128
5.7.5 值類(lèi)型拋出,常量引用類(lèi)型捕獲130
5.7.6 注意catch的正確順序130
第6章 面向?qū)ο?31
6.1 面向?qū)ο笏枷?32
6.2 抽象解決復(fù)雜問(wèn)題的關(guān)鍵因素133
6.3 類(lèi)的設(shè)計(jì)原則134
6.3.1 讓類(lèi)盡可能小134
6.3.2 單一職責(zé)原則(SRP)135
6.3.3 開(kāi)閉原則(OCP)135
6.3.4 里氏替換原則(LSP)136
6.3.5 接口隔離原則(ISP)146
6.3.6 無(wú)環(huán)依賴原則148
6.3.7 依賴倒置原則(DIP)151
6.3.8 不要和陌生人說(shuō)話(迪米特法則)156
6.3.9 避免貧血類(lèi)160
6.3.10 只說(shuō)不問(wèn)160
6.3.11 避免類(lèi)的靜態(tài)成員162
第7章 函數(shù)式編程164
7.1 什么是函數(shù)式編程165
7.1.1 什么是函數(shù)166
7.2.2 pure函數(shù)和impure函數(shù)167
7.2 現(xiàn)代C 中的函數(shù)式編程168
7.2.1 C 模板函數(shù)編程168
7.2.2 仿函數(shù)170
7.2.3 綁定和函數(shù)包裝176
7.2.4 Lambda表達(dá)式178
7.2.5 通用Lambda表達(dá)式(C 14)180
7.3 高階函數(shù)181
7.4 整潔的函數(shù)式編程代碼186
第8章 測(cè)試驅(qū)動(dòng)開(kāi)發(fā)188
8.1 普通的舊單元測(cè)試的缺點(diǎn)189
8.2 測(cè)試驅(qū)動(dòng)開(kāi)發(fā)作為顛覆者190
8.2.1 TDD的流程190
8.2.2 TDD的一個(gè)小例子:Code Kata193
8.3 TDD的優(yōu)勢(shì)210
8.4 什么時(shí)候不應(yīng)該使用TDD212
第9章 設(shè)計(jì)模式和習(xí)慣用法213
9.1 設(shè)計(jì)原則與設(shè)計(jì)模式214
9.2 常見(jiàn)的設(shè)計(jì)模式及應(yīng)用場(chǎng)景214
9.2.1 依賴注入模式215
9.2.2 Adapter模式226
9.2.3 Strategy模式227
9.2.4 Command模式231
9.2.5 Command處理器模式235
9.2.6 Composite模式238
9.2.7 Observer模式241
9.2.8 Factory模式245
9.2.9 Facade模式248
9.2.10 Money Class模式249
9.2.11 特例模式252
9.3 什么是習(xí)慣用法255
附錄A UML簡(jiǎn)要指南266
參考文獻(xiàn)275