
何為重構(gòu)
重構(gòu):在不改變軟件對外表現(xiàn)和行為的前提下修改已有代碼使其易于理解,便于擴(kuò)展
重構(gòu)就是讓代碼易于程序猿理解。在重構(gòu)的世界里代碼是寫給程序猿看的而非寫給機(jī)器看,我們會(huì)忽視性能而專注于讓代碼對程序猿更友好(先讓代碼跑通,再去重構(gòu),最后才考慮性能優(yōu)化)
為什么要重構(gòu)
- 在添加功能前重構(gòu),可以時(shí)原有的代碼更易擴(kuò)展,簡化功能添加難度
- 在改bug前重構(gòu),可以優(yōu)化代碼的結(jié)構(gòu),使邏輯更加清晰,更容易找出bug
- 在評審代碼時(shí)(無論是自己的還是別人的代碼都行)進(jìn)行重構(gòu),可以加深對代碼邏輯的理解
重復(fù)一遍:
| 重構(gòu)時(shí)機(jī) | 好處 |
|---|---|
| 添加功能前 | 更易擴(kuò)展 |
| 改bug前 | 更易找出bug |
| 評審代碼時(shí) | 加深理解 |
怎么重構(gòu)
看圖:

第一步 建立測試框架
測試框架是判斷重構(gòu)成功與否的關(guān)鍵,再重復(fù)一遍:
重構(gòu):在不改變軟件對外表現(xiàn)和行為的前提下修改已有代碼使其易于理解,便于擴(kuò)展
重構(gòu)不能改變代碼對外的表現(xiàn)和行為,測試框架正是要測試重構(gòu)是否改變了代碼的對外接口,如果不能通過測試,必須對重構(gòu)進(jìn)行修復(fù)(回滾到重構(gòu)之前)
第二步 尋找代碼壞味
代碼壞味(Bad Smell),出自《重構(gòu)——改善既有代碼的設(shè)計(jì)》的作者,作者認(rèn)為代碼的不合理設(shè)計(jì)就像嬰兒的尿布散發(fā)出來的Bad Smell一樣,當(dāng)你聞到它的時(shí)候,就應(yīng)該警惕:該給代碼換尿布了
我們要重構(gòu)代碼,首先要找出需要重構(gòu)的地方,作者總結(jié)了幾種特殊“味道”的Bad Smell,我把它寫在了【怎么重構(gòu)】的下面(代碼壞味)
第三步 代碼重構(gòu)
使用針對代碼壞味的重構(gòu)手段對其進(jìn)行重構(gòu)即可
第四步 測試
使用第一步建立的測試框架對重構(gòu)進(jìn)行測試
重構(gòu)可不是寫B(tài)ug
代碼壞味
我只收錄了《重構(gòu)——改善既有代碼的設(shè)計(jì)》中一部分常見的代碼壞味,更多的請查看原書
我極力推薦給大家這本書:世界軟件開發(fā)大師Martin Fowler的《重構(gòu)——改善既有代碼的設(shè)計(jì)》
| 壞味 | 表現(xiàn) | 對應(yīng)的重構(gòu)手段 |
|---|---|---|
| 重復(fù)代碼塊 | 相同代碼重復(fù)出現(xiàn) | 抽取方法 |
| 方法過長 | 方法體長度超過30行 | 抽取方法 |
| 方法參數(shù)過多 | 方法所需的參數(shù)超過3個(gè) | 使用對象封裝參數(shù)集 |
| 臨時(shí)變量存在 | 代碼中有臨時(shí)變量 | 使用查詢方法取代臨時(shí)變量 |
| switch語句存在 | 代碼中有switch分支 | 使用多態(tài)取代switch分支 |
| 類過長 | 類的長度超過100行 | 轉(zhuǎn)移成員變量和函數(shù)<br />抽取類 |
| 發(fā)散式變化 | 引發(fā)一個(gè)類修改的原因不只一個(gè) | 抽取類 |
| 發(fā)散式修改 | 一個(gè)類修改,引發(fā)修改的其他類不止一個(gè) | 抽取類 |
| 數(shù)據(jù)依賴&過度親密 | 一個(gè)類過多調(diào)用另一個(gè)類的成員和函數(shù)(甚至超過了擁有成員和函數(shù)的類) | 轉(zhuǎn)移成員變量和函數(shù) |
重構(gòu)手段
等我把這些文章全寫完發(fā)了,再給你們提供鏈接
-
到處都是重復(fù)的代碼?方法體又臭又長看不懂?快來試試抽取方法(Extract Method)吧,保證藥到病除!
-
使用對象封裝參數(shù)集
答應(yīng)我,別再給方法弄一長溜的參數(shù)了,好嗎?
-
使用查詢方法取代臨時(shí)變量
你這方法里怎么這么多臨時(shí)變量?我完全記不住每個(gè)變量是用來干什么的!
-
使用多態(tài)取代switch分支
“來看看外包老哥寫的超長switch語句”這種文章又登上首頁了
-
及時(shí)打斷if條件分支
外包老哥總是被黑的幕后黑手找到了!
-
轉(zhuǎn)移成員變量和函數(shù)
道理我都懂,可是你一直在用的成員變量為什么要讓我負(fù)責(zé)管理?
-
抽取類
總覺得,是時(shí)候new一個(gè)替身出來幫我干活了
-
將數(shù)據(jù)的處理函數(shù)轉(zhuǎn)移給持有數(shù)據(jù)的類
或許,這個(gè)鍋應(yīng)該由你來背
-
向父類轉(zhuǎn)移成員變量和函數(shù)
所有子類都需要做的事,為什么不讓父類直接做了?
-
注意集合型成員變量的get/set方法!
有人動(dòng)了我的集合對象,可是我卻不知道!
技術(shù)不分領(lǐng)域,思想一脈相承,歡迎訪問橙味菌的博客
本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布!