本書的主要內(nèi)容有:理解代碼是如何退化的,以及為什么一些退化是不可避免的。在重構(gòu)之前,量化和評定你的代碼狀態(tài)。起草一個具有戰(zhàn)略里程碑且精心設(shè)計的執(zhí)行計劃。贏得領(lǐng)導(dǎo)層的支持。建立和協(xié)調(diào)一個最z適合項目的團(tuán)隊。在團(tuán)隊內(nèi)外進(jìn)行高效溝通。正確使用重構(gòu)的最z佳實踐。
一句話推薦
重獲代碼的控制權(quán)
編輯推薦
對大型、復(fù)雜的代碼庫進(jìn)行重大修改是一項艱巨的任務(wù),除非你有合適的團(tuán)隊、工具和思維方式,否則幾乎不可能成功。如果你的應(yīng)用程序需要進(jìn)行重大改造,但你又不確定以何種可持續(xù)的方式進(jìn)行,那么這本書就是為你準(zhǔn)備的。
軟件工程師Maude Lemaire將帶領(lǐng)你從頭到尾經(jīng)歷整個重構(gòu)過程。你將了解她在Slack的關(guān)鍵發(fā)展時期是如何提高性能和重構(gòu)的,并從這些經(jīng)驗中得到啟發(fā),書中利用兩個案例研究來說明這些技術(shù)是如何在實際工作中產(chǎn)生影響的。本書將有助于你獲得一種新的能力,使你更高效地進(jìn)行重構(gòu)。
專家推薦
在一個巨大的、不斷變化的代碼庫中,保持生產(chǎn)力似乎是一個西西弗斯式的任務(wù)。本書將這一過程分解成一個個你可以立即應(yīng)用的步驟。
Cal Henderson
Slack首席技術(shù)官
我喜歡這本書中的案例研究。我希望我能把這本書送給過去的自己,幫助以前的我更好的規(guī)劃大型遷移。書中有很多我需要去努力學(xué)習(xí)的經(jīng)驗。
Julia Evans
《Wizard Zines》的作者
前言雖然有很多關(guān)于重構(gòu)的書籍,但大多數(shù)都是處理如何一行行改進(jìn)代碼的細(xì)節(jié)問題。我認(rèn)為重構(gòu)最困難的部分通常不是找到改進(jìn)手頭代碼的精確方法,而是需要在其周圍進(jìn)行的所有其他事情。事實上,我甚至可能會說,在任何大型軟件項目中,小事情很少有意義,協(xié)調(diào)復(fù)雜的變化才是最大的挑戰(zhàn)。這本書是我試圖幫助你解決那些困難問題的嘗試。它是多年經(jīng)驗的結(jié)晶,我曾經(jīng)進(jìn)行過各種規(guī)模的重構(gòu)項目。在Slack 任職期間,我領(lǐng)導(dǎo)的許多項目使公司得以大規(guī)模擴(kuò)展,我們的產(chǎn)品已經(jīng)能夠支持擁有25000 名員工的客戶,甚至是擁有高達(dá)500000 名員工的客戶。我們開發(fā)的有效重構(gòu)策略需要能夠適應(yīng)組織的爆炸性增長,與此同時,我們的工程團(tuán)隊在同一時期幾乎增長了6 倍。成功地規(guī)劃和執(zhí)行一個既影響到你的大部分代碼庫又涉及越來越多工程師的項目絕非易事。我希望這本書能給你提供你所需要的工具和資源來做到這一點。誰應(yīng)該閱讀這本書如果你在與幾十個甚至更多的工程師一起處理大型、復(fù)雜的代碼庫,那么本書就適合你!如果你是一名初級工程師,想通過對公司產(chǎn)生廣泛、有意義的影響并開始構(gòu)建更高級別的技能,大規(guī)模重構(gòu)項目可以是實現(xiàn)這一目標(biāo)的好方法。這些項目的影響范圍廣泛,超越了你所在的團(tuán)隊(它們也不是高級工程師馬上就能搶走的那種光鮮項目)。這是一個非常好的機(jī)會,讓你獲得新的專業(yè)技能(并加強(qiáng)你已有的技能)。本書將教會你如何從頭到尾順利地完成這類項目。本書也是高度技術(shù)性的高級工程師的有價值資源,這類工程師可以自己編寫沒有任何問題的代碼,但卻感到其他人不理解他們工作的價值而感到沮喪。如果你感到孤立無援,正在尋找方法提升你周圍其他人的水平,本書可以教給你所需的策略,幫助他人從你的角度看到重要的技術(shù)問題。對于希望幫助團(tuán)隊通過大規(guī)模重構(gòu)的技術(shù)經(jīng)理,本書可以幫助你了解如何在每個步驟中更好地支持你的團(tuán)隊。這里沒有大量的技術(shù)內(nèi)容,因此,如果你會以管理的角色參與到大規(guī)模重構(gòu)(工程經(jīng)理、產(chǎn)品經(jīng)理、項目經(jīng)理),都可以從這些思想中受益。為什么寫這本書當(dāng)我開始進(jìn)行第一個大規(guī)模的重構(gòu)時,我理解代碼需要改變的原因和方式,但最困惑我的是如何安全、逐步地引入這些變化,而不會傷及其他人的利益。我渴望產(chǎn)生跨職能影響,并沒有停下來思考重構(gòu)可能對其他人的工作產(chǎn)生的影響,以及我如何激勵他們幫助我完成它。我只是一直在沖刺(可以在第10 章中閱讀有關(guān)此重構(gòu)的內(nèi)容)。隨后的幾年中,我重構(gòu)了許多行代碼,并成為一些重構(gòu)不當(dāng)?shù)氖芎φ。我從這些經(jīng)歷中學(xué)到的教訓(xùn)似乎很重要,因此我開始在許多會議上演講。我的演講引起了數(shù)百名工程師的共鳴,他們都像我一樣,在自己的公司中經(jīng)歷了有效重構(gòu)大面積代碼的問題。顯然,我們的軟件教育存在某種差距,特別是在專業(yè)軟件編寫的核心方面。在許多方面,這本書試圖教授計算機(jī)科學(xué)課程中未涵蓋的重要內(nèi)容,僅僅因為在課堂上教授這些內(nèi)容太困難了。也許這些內(nèi)容在書中也無法教授,但為什么不試一試呢?本書的組織結(jié)構(gòu)本書分為四部分,按照計劃和執(zhí)行大規(guī)模重構(gòu)所需的工作的大致時間順序進(jìn)行組織,如下所述。 第一部分概述。介紹重構(gòu)背后的重要概念。─ 第 1 章重構(gòu)。討論了重構(gòu)的基礎(chǔ)知識以及對比大規(guī)模重構(gòu)與較小規(guī)模的重構(gòu)有何不同。─ 第 2 章代碼是如何退化的。描述代碼可能退化的多種方式以及如何將其納入有效的重構(gòu)中。 第二部分規(guī)劃。涵蓋了計劃成功重構(gòu)所需的所有知識。─ 第 3 章測量我們的起點狀態(tài)。提供一個概述,介紹在進(jìn)行任何改進(jìn)之前,你可以使用哪些指標(biāo)來衡量你的重構(gòu)旨在解決的問題。─ 第 4 章起草計劃。解釋了一個全面的執(zhí)行計劃的重要組成部分以及如何制定一個執(zhí)行計劃。─ 第 5 章獲取支持。討論了不同的方法來獲取工程領(lǐng)導(dǎo)支持你的重構(gòu)。─ 第 6 章構(gòu)建正確的團(tuán)隊。描述了如何確定哪些工程師最適合參與重構(gòu)以及如何為他們提供建議。 第三部分執(zhí)行。關(guān)注在重構(gòu)過程中如何確保重構(gòu)順利進(jìn)行。─ 第 7 章溝通。探討如何最好地促進(jìn)團(tuán)隊內(nèi)部和與任何外部利益相關(guān)者之間的良好溝通。─ 第 8 章執(zhí)行策略?纯慈绾卧谥貥(gòu)過程中保持動力的幾種方法。─ 第 9 章讓重構(gòu)保持有效。提供了幾個建議,以確保你進(jìn)行的重構(gòu)所引入的更改得以保留。 第四部分用例,包含兩個案例研究,都是從我在Slack 工作期間參與的項目中提取的。這些重構(gòu)影響了我們核心應(yīng)用程序的大部分,真正地達(dá)到了規(guī)模。我希望這些能夠幫助闡述書中第一部分到第三部分討論的概念。這個順序并不是一成不變的,僅僅因為我們進(jìn)入了新的階段,并不意味著我們不應(yīng)該在必要時重新審視我們之前的假設(shè)。例如,你可能會以一個強(qiáng)烈的團(tuán)隊意識開始你的重構(gòu)工作,但是在起草執(zhí)行計劃的過程中,你可能會發(fā)現(xiàn)你需要比最初預(yù)期的更多的工程師。這沒關(guān)系,這種情況經(jīng)常發(fā)生!排版約定本書使用以下排版約定。斜體(Italic)表示新術(shù)語、URL、電子郵件地址、文件名和文件擴(kuò)展名。等寬字體(Constant width)表示程序片段,以及正文中出現(xiàn)的程序元素,例如變量、函數(shù)名、數(shù)據(jù)類型、語句和關(guān)鍵字。使用代碼示例補(bǔ)充材料(代碼示例、練習(xí)等)可在以下鏈接下載:https://github.com/qcmaude/refactoring-at-scale。本書是要幫你完成工作的。一般來說,如果本書提供了示例代碼,你可以把它用在你的程序或文檔中。除非你使用了很大一部分代碼,否則無需聯(lián)系我們獲得許可。比如,用本書的幾個代碼片段寫一個程序就無需獲得許可。銷售或分發(fā)OReilly圖書的示例需要獲得許可,引用本書中的示例代碼回答問題無需獲得許可,將書中大量的代碼放到你的產(chǎn)品文檔中需要獲得許可。我們很希望但并不強(qiáng)制要求你在引用本書內(nèi)容時加上引用說明。引用說明一般包括書名、作者、出版社和ISBN,例如:Refactoring at Scale by Maude Lemaire(OReilly). Copyright 2021 Maude Lemaire, 978-1-492-07553-0 。如果你覺得自己對示例代碼的使用超出了上述許可范圍,請通過permissions@oreilly.com 與我們聯(lián)系。OReilly 在線學(xué)習(xí)平臺(OReilly Online Learning)近40 年來,OReilly Media 致力于提供技術(shù)和商業(yè)培訓(xùn)、知識和卓越見解,來幫助眾多公司取得成功。公司獨(dú)有的專家和改革創(chuàng)新者網(wǎng)絡(luò)通過OReilly 書籍、文章以及在線學(xué)習(xí)平臺,分享他們的專業(yè)知識和實踐經(jīng)驗。OReilly 在線學(xué)習(xí)平臺按照您的需要提供實時培訓(xùn)課程、深入學(xué)習(xí)渠道、交互式編程環(huán)境以及來自O(shè)Reilly 和其他200 多家出版商的大量書籍與視頻資料。更多信息,請訪問網(wǎng)站:https://www.oreilly.com/。聯(lián)系我們?nèi)魏斡嘘P(guān)本書的意見或疑問,請按照以下地址聯(lián)系出版社。美國:OReilly Media, Inc.1005 Gravenstein Highway NorthSebastopol, CA 95472中國:北京市西城區(qū)西直門南大街2 號成銘大廈C 座807 室(100035)奧萊利技術(shù)咨詢(北京)有限公司勘誤、示例和其他信息,請訪問https://oreil.ly/refactoring-at-scale。對于本書的評論和技術(shù)性問題,請發(fā)送電子郵件到errata@oreilly.com.cn。要了解更多OReilly 圖書和培訓(xùn)的信息,請訪問https://oreilly.com。我們的Facebook:https://linkedin.com/company/oreilly-media。我們的Twitter:https://twitter.com/oreillymedia。我們的YouTube:https://www.youtube.com/oreillymedia。致謝寫一本書并不是一件容易的事情,這本書也不例外,沒有很多人的貢獻(xiàn)是不可能完成的。首先,我要感謝OReilly 的編輯Jeff Bleiel。Jeff 把一個沒有經(jīng)驗的作者(我)變成了一位出版的作者。他的反饋總是非常準(zhǔn)確,幫助我更有條理地組織我的思路,并鼓勵我在我寫得太啰嗦時進(jìn)行刪減(這種情況經(jīng)常發(fā)生)。我簡直無法想象有比他更好的編輯。其次,我要感謝少數(shù)幾個朋友和同事,他們閱讀了幾章的早期版本:Morgan Jones、Ryan Greenberg 和Jason Liszka。他們的反饋讓我確信我的想法是正確的,并且對廣泛的讀者有價值。對于鼓勵和引發(fā)思考的談話,感謝Joann、Kevin、Chase 和Ben。我要感謝Maggie Zhou,在第二個案例研究章節(jié)(第11 章)中與我共同撰寫。她是我曾經(jīng)一起工作過的最有思想、最聰明、最有活力的同事之一,我很高興讓世界讀到我們一起的冒險!非常感謝我的技術(shù)審稿人David Cottrell 和Henry Robinson。David 是我大學(xué)時的好朋友,在Google 工作多年,領(lǐng)導(dǎo)了許多大規(guī)模的重構(gòu)。他后來創(chuàng)立了自己的公司。Henry 是我在Slack 的同事,做出了無數(shù)的開源貢獻(xiàn),并親眼見證了硅谷公司的爆炸式增長。他們都是非常有責(zé)任心的工程師,這本書從他們的指導(dǎo)和智慧中受益匪淺。我感激他們花費(fèi)許多時間來驗證書中的內(nèi)容。最終手稿中的任何不準(zhǔn)確之處都是我的錯誤。感謝所有曾經(jīng)和我一起重構(gòu)過東西的人。你們太多了,無法一一列舉,但你們知道自己是誰。你們都對本書中的思想產(chǎn)生了影響。感謝我的家人(Simon、Marie-Josée、Fran?ois-Rémi、Sophie、Sylvia、Gerry、Stephanie 和Celia)在場外為我加油。最后,感謝我的丈夫Avery。謝謝你的耐心,謝謝你給我寫作的時間、空間和鼓勵。謝謝你讓我占用了無數(shù)個下午來討論一個、兩個(或三個、四個)想法。謝謝你相信我。這本書和你一樣屬于我。我愛你。
Maude Lemaire是Slack的一名軟件工程師,她的工作是提升產(chǎn)品性能,以支持一些世界上最z大的組織。她的大部分時間都在進(jìn)行人員管理、網(wǎng)絡(luò)調(diào)用、重構(gòu)復(fù)雜的代碼塊、整合冗余的數(shù)據(jù)庫,以及為其他開發(fā)者構(gòu)建工具。
目錄
前言 1
第一部分 概述
第1 章 重構(gòu) 11
1.1 什么是重構(gòu)? .12
1.2 什么是大規(guī)模重構(gòu)? 14
1.3 你為什么要關(guān)心重構(gòu)? .16
1.4 重構(gòu)的好處 17
1.4.1 開發(fā)者的生產(chǎn)力 17
1.4.2 識別bug 19
1.5 重構(gòu)的風(fēng)險 19
1.5.1 嚴(yán)重的退步 20
1.5.2 挖掘出休眠的bug 20
1.5.3 范圍蔓延 .20
1.5.4 不必要的復(fù)雜度 21
1.6 何時重構(gòu)21
1.6.1 小范圍 22
1.6.2 代碼的復(fù)雜度明顯地阻礙了開發(fā) 22
1.6.3 產(chǎn)品需求的轉(zhuǎn)變 22
1.6.4 性能 23
1.6.5 使用新技術(shù) 23
1.7 何時不要重構(gòu) .24
1.7.1 為了好玩或出于無聊的原因 .24
1.7.2 因為你恰好路過 25
1.7.3 使代碼更具可擴(kuò)展性.26
1.7.4 當(dāng)你沒時間時 27
1.8 我們的第一個重構(gòu)示例 .27
1.8.1 簡化條件語句 29
1.8.2 提取魔法數(shù)字 31
1.8.3 提取自包含邏輯 32
第2 章 代碼是如何退化的 .37
2.1 為什么理解代碼退化很重要 38
2.2 需求的轉(zhuǎn)變 39
2.2.1 可擴(kuò)展性 .39
2.2.2 可訪問性 .40
2.2.3 設(shè)備兼容性 40
2.2.4 環(huán)境改變 .41
2.2.5 外部依賴 .42
2.2.6 未使用的代碼 42
2.2.7 產(chǎn)品需求變化 43
2.3 技術(shù)債 46
2.3.1 技術(shù)決策 .47
2.3.2 缺乏持續(xù)的整理 50
2.3.3 移動得太快 51
2.4 應(yīng)用我們的知識 53
第二部分 規(guī)劃
第3 章 測量我們的起點狀態(tài) .57
3.1 為什么測量重構(gòu)的影響很難? 58
3.2 測量代碼復(fù)雜性 59
3.2.1 哈爾斯特德(Halstead)度量 59
3.2.2 循環(huán)復(fù)雜度 62
3.2.3 NPath 復(fù)雜度 65
3.2.4 代碼行數(shù) .68
3.3 測試覆蓋率指標(biāo) 69
3.4 文檔 .73
3.4.1 正式文檔 .73
3.4.2 非正式文檔 75
3.5 版本控制76
3.5.1 提交信息 .77
3.5.2 聚合提交 .77
3.6 聲譽(yù) .79
3.7 構(gòu)建完整的畫面 82
第4 章 起草計劃 83
4.1 定義你的最終狀態(tài) 84
4.1.1 旅途中 84
4.1.2 工作中 85
4.2 映射最短的距離 86
4.2.1 旅途中 86
4.2.2 工作中 87
4.3 確定戰(zhàn)略中間里程碑 89
4.3.1 旅途中 89
4.3.2 工作中 90
4.4 選擇推出策略 .94
4.4.1 明模式(Light)/ 暗模式(Dark) 95
4.4.2 Smart DNA 案例的推出 99
4.5 清理工件.100
4.6 在你的計劃中引用指標(biāo) 102
4.6.1 將目標(biāo)指標(biāo)延伸至中間里程碑 102
4.6.2 不同的里程碑指標(biāo) 103
4.7 估算 104
4.8 與其他團(tuán)隊分享你的計劃 .105
4.8.1 透明度 106
4.8.2 觀點 .106
4.9 精細(xì)化計劃 108
第5 章 獲取支持 111
5.1 為什么你的經(jīng)理沒有上船 . 112
5.1.1 經(jīng)理不編碼 . 112
5.1.2 經(jīng)理們的評估方式不同 . 113
5.1.3 管理者看到的風(fēng)險 113
5.1.4 管理者需要協(xié)調(diào) 114
5.2 制定令人信服的策略 115
5.2.1 使用對話策略 . 117
5.2.2 構(gòu)建對齊的三明治 . 118
5.2.3 依賴證據(jù) 121
5.2.4 采取強(qiáng)硬手段 .122
5.3 認(rèn)同塑造重構(gòu) 124
第6 章 構(gòu)建正確的團(tuán)隊 125
6.1 識別不同類型的專家 126
6.2 匹配制度.128
6.2.1 多行業(yè)專家 .129
6.2.2 重新審視活躍貢獻(xiàn)者130
6.2.3 我們專家名單中的偏見 .130
6.3 重構(gòu)團(tuán)隊的類型 .132
6.3.1 所有者 132
6.3.2 建議的方法 .134
6.3.3 清潔人員 134
6.4 招募動員.136
6.4.1 指標(biāo) .137
6.4.2 慷慨 .138
6.4.3 機(jī)會 .139
6.4.4 交換籌碼 139
6.4.5 重復(fù) .140
6.5 一些結(jié)果.141
6.5.1 現(xiàn)實的場景 .141
6.5.2 最壞的情況 .141
6.6 培養(yǎng)強(qiáng)大的團(tuán)隊 .142
第三部分 執(zhí)行
第7 章 溝通 . 147
7.1 在你的團(tuán)隊內(nèi) 148
7.1.1 站會 .150
7.1.2 每周同步 151
7.1.3 回顧會議 153
7.2 在你的團(tuán)隊外 154
7.2.1 開始項目時 .154
7.2.2 在項目執(zhí)行期間 157
7.3 始終迭代.162
第8 章 執(zhí)行策略 . 163
8.1 團(tuán)隊建設(shè).163
8.1.1 結(jié)對編程 164
8.1.2 保持每個人的動力 166
8.2 保持記錄.168
8.2.1 中期指標(biāo)度量 .168
8.2.2 發(fā)現(xiàn)的漏洞 .169
8.2.3 清理項 170
8.2.4 記錄超出范圍的內(nèi)容170
8.3 高效編程.171
8.3.1 原型 .171
8.3.2 保持事物小巧 .172
8.3.3 測試,測試,測試 173
8.3.4 提出愚蠢的問題173
8.4 結(jié)論 174
第9 章 讓重構(gòu)保持有效 175
9.1 推動支持.176
9.2 傳授 177
9.2.1 主動傳授 177
9.2.2 被動傳授 180
9.3 強(qiáng)化 181
9.3.1 漸進(jìn)式代碼檢查 181
9.3.2 代碼分析工具 .182
9.3.3 門檻與護(hù)欄 .182
9.4 將改進(jìn)融入企業(yè)文化 184
第四部分 用例
第10 章 案例研究:冗余數(shù)據(jù)庫模式(Schemas) 189
10.1 Slack 101 .190
10.2 Slack 架構(gòu)101 192
10.3 可擴(kuò)展性問題 195
10.3.1 啟動Slack 客戶端 .196
10.3.2 文件可見性196
10.3.3 提及 197
10.4 合并表格 198
10.4.1 收集分散的查詢 .199
10.4.2 制定遷移策略 202
10.4.3 量化我們的進(jìn)展 .205
10.4.4 試圖保持團(tuán)隊的動力 206
10.4.5 溝通我們的進(jìn)展 .207
10.5 整理 209
10.6 經(jīng)驗教訓(xùn) 211
10.7 了解代碼的歷史 212
10.7.1 確保充分的測試覆蓋率 213
10.7.2 保持團(tuán)隊的動力 .213
10.7.3 專注于戰(zhàn)略里程碑 214
10.7.4 識別并依賴有意義的指標(biāo) .214
10.8 收獲 215
第11 章 案例研究:遷移到新數(shù)據(jù)庫 217
11.1 工作區(qū)分片數(shù)據(jù) 218
11.2 將channels_members 遷移到Vitess 219
11.2.1 分片方案 220
11.2.2 開發(fā)新模式 221
11.3 解決JOIN 操作中的糾纏問題 224
11.4 一個困難的推出 228
11.4.1 回填模式 229
11.4.2 暗模式 .230
11.4.3 明模式 .235
11.4.4 日落模式 237
11.5 整理 237
11.6 經(jīng)驗教訓(xùn) 239
11.6.1 設(shè)定現(xiàn)實的估算 .240
11.6.2 尋找你需要的團(tuán)隊成員 240
11.6.3 仔細(xì)規(guī)劃范圍 241
11.6.4 選擇一個項目溝通的單一地點 241
11.6.5 設(shè)計一個周到的推出計劃 .242
11.7 收獲 243