第3章 代碼的壞味道
1.神秘命令(Mysterious Name)?
- 整潔代碼中最重要的一環(huán)就是有一個好名字烫罩,使他們能夠清晰地表明自己的功能和用法。
- 但正因為如此约素,命名就成了編程中最難的兩件事之一届良。
- 而在重構中改名是最常用的重構手法,包括改變函數(shù)聲明圣猎,變量名士葫,字段名等。
- 記住送悔,改名不僅僅是修改名字而已慢显,若想不出一個好的名字,說明背后可能存在更深的設計問題欠啤。
2. 重復代碼(Duplicated Code)?
- 最簡單的重復代碼就是在一個類或方法總荚藻,存在兩個函數(shù)相同相同的表達式。
- 此時可采用提煉函數(shù)的方式來提煉出重復的代碼跪妥,然后讓重復調用這段代碼的地方都改為同一個函數(shù)命名鞋喇。
- 若重復的代碼只是很相似,而不是晚安全相同眉撵,可嘗試移動語句順序來進行重組侦香。
3. 過長函數(shù)(Long Function)?
活的最長,最好的程序纽疟,其中的函數(shù)都較短罐韩。
函數(shù)越長,就越難理解
-
但其實小函數(shù)也會給代碼的閱讀者帶來一些負擔污朽,因為要經(jīng)常切換上下文散吵,才能看明白函數(shù)在做什么。若能給函數(shù)起一個好名字蟆肆,閱讀代碼的人就可以通過名字了解函數(shù)的作用矾睦,根本不用去看函數(shù)的實現(xiàn)。
3.1 如何提煉函數(shù)的參數(shù)和臨時變量炎功?
- 可運用查詢取代臨時變量來消除臨時變量
- 可使用參數(shù)對象的方式將過長的參數(shù)裂變的更簡潔一些
- 若使用以上兩種方式還是存在太多的臨時變量和參數(shù)枚冗,那就上我們的殺手锏——以命令取代函數(shù)。
3.2 如何確定提煉某個文件下某一段的代碼呢蛇损?
-
一個好技巧:尋找注釋
- 注釋可指出代碼用途和實現(xiàn)手法之間的語義距離赁温。若只有一行代碼坛怪,還需要以注釋來說明,那也值得將它提煉到獨立的函數(shù)中股囊。
-
遇到條件表達式和循環(huán)
- 如在將循環(huán)和循環(huán)內的代碼提煉到一個獨立的函數(shù)中時遇到難以為獨立的函數(shù)命名袜匿,這可能是因為這段代碼其中做了幾件不同的事情。若是遇到這種情況稚疹,更要進行拆分居灯。
4. 全局數(shù)據(jù)(Global Data)?
- 全局數(shù)據(jù)印證了帕拉塞爾斯的格言:良藥與毒藥的區(qū)別在于劑量。
- 少量對的全局數(shù)據(jù)或許無妨内狗,但隨著數(shù)量增多穆壕,處理的難度就會呈指數(shù)增長。
5. 可變數(shù)據(jù)(Mutable Data)?
- 在程序中其屏,我們有時候修改了某一處的數(shù)據(jù),然而卻沒有意識到軟件中的另一處地方也在使用缨该,或者另一處需要一個新的數(shù)據(jù)結構偎行。
6. 發(fā)散式變化(Divergent Change)?
- 在程序設計中,我們都希望軟件能夠容易被修改贰拿,畢竟軟件本身就是“軟”的蛤袒。
- 當我們要對某個上下文做修改時,我們只需要理解這個上下文膨更,而不必操作另一個妙真。
- “每次只關心一個上下文”這一點很重要
7. 霰彈式修改(Shotgun Surgery)?
-
霰彈式的修改類似于發(fā)散式變化,但卻恰恰相反荚守。
7.1 何為霰彈式修改珍德?
- 如果當遇到某種變化,你都必須在許多不同的類中做出許多小修改矗漾,你所面臨的壞味道就是霰彈式修改锈候。
7.2 如何對霰彈式的程序進行修改?
- 可使用搬移函數(shù)敞贡,將所有需要修改的代碼放進同一個模塊中
- 如果有很多函數(shù)在操作相同的是數(shù)據(jù)泵琳,可將這些函數(shù)整合成類
- 常用策略是使用內聯(lián)相關的重構,如內聯(lián)函數(shù)誊役,內聯(lián)類等等获列,把本不該分散的邏輯組合在一處。
8. 依戀情結(Feature Envy)蛔垢?
-
依戀情結的情況:比如一個函數(shù)跟另一個模塊中的函數(shù)或數(shù)據(jù)交流很頻繁击孩。
8.1 何為模塊化?
- 將代碼分出區(qū)域啦桌,最大化區(qū)域內部的交互溯壶,最小化跨區(qū)域的交互及皂。
-
8.2 有時候一個函數(shù)中往往會用到幾個模塊中的功能,那如何處理這種依戀情結呢且改?
- 可以判斷哪個模塊擁有的當前函數(shù)使用的數(shù)據(jù)最多验烧,然后就可以把這個函數(shù)和數(shù)據(jù)放在一起。
9. 數(shù)據(jù)泥團(Data Clumps)?
數(shù)據(jù)項像小孩子一樣又跛,喜歡成群結隊待在一起碍拆。
-
9.1 如何評判眾多數(shù)據(jù)是否有價值?
- 刪掉眾多數(shù)據(jù)中的一項,然后看其他數(shù)據(jù)有沒有因刪掉的數(shù)據(jù)項而失去存在意義慨蓝,如果不再有意義感混,那就是一個明確的信號,你應該為他們產生一個新對象礼烈。
10. 過長的消息鏈(Message Chains)?
-
何為過長的消息鏈弧满?
- 一個用戶向一個對象請求另一個對象,然后再想后者請求另一個對象此熬,然后再請求另一個對對象庭呜,循環(huán)往復。
-
如何針對過長的消息連進行重構犀忱?
- 先觀察消息連最終得到的對象時用來干什么的募谎,看看能否以提煉函數(shù)把使用該對象的代碼提煉到一個獨立的函數(shù)中,再運用搬移函數(shù)把這個函數(shù)推入到消息鏈中阴汇。
- 如果還有許多客戶端代碼需要訪問鏈上的其他對象数冬,同樣添加一個函數(shù)來完整此事。
11. 注釋(Comments)?
- 注釋并不是一件壞事搀庶,有時候它還是一個好事拐纱。
- 當你感覺需要編寫注釋時,請先嘗試重構代碼地来,試著讓所有注釋都變得多余戳玫。
第4章 構筑測試體系
1. 自測試代碼的價值?
能夠確保所有測試都完全自動化未斑,讓他們檢查自己的測試結果咕宿。
當完成一個功能后,就開始編寫測試代碼可以更好的提高開發(fā)效率蜡秽。
一套測試就是一個強大的bug偵測器府阀,能夠大大縮減查找bug所需的時間。
-
將測試代碼的習慣提煉成一個技藝芽突?
- 這個技藝就是測試驅動開發(fā)(Test-Driven Development, TDD)
-
測試驅動開發(fā)的短循環(huán)试浙?
- 先編寫一個測試 —> 編寫業(yè)務代碼 —> 重構。然后這個 “測試寞蚌、編碼田巴、重構” 這個循環(huán)在我們日常開發(fā)中要完成很多次钠糊。
2. 本章所講的內容?
- 帶著你走進自測試代碼世界的大門壹哺,從簡單的例子開始抄伍。
第5章 介紹重構目錄
1. 重構的記錄格式?
-
每個重構手法都有 5 個部分
- 名稱(name):建構一個重構詞匯名稱的對應表
- 速寫(sketch):幫助我們更快的找到所需要的手法
- 動機(motivation):會介紹 “為什么需要做這個重構”和 “什么情況下不該做這個重構”
- 做法(mechanics):如何一步一步進行重構
- 范例(examples):以一個簡單的例子來說明此重構手法如何運作
牢記重構的一點:小步前進管宵,情況越復雜截珍,步子就要越小