重構帶來的好處為何?如何重構?
2023年3月3日
💎 加入 E+ 成長計畫 如果你喜歡我們的內容,歡迎加入 E+,獲得更多深入的軟體前後端內容
什麼是重構?
重構 (Refactoring)指的是「在不改變外部行為的情況下,重組程式碼的過程」,因此對於外部用戶而言,重構與否是沒有感覺的,但重構的好處在於:
- 提高可讀性:通過重構,程式碼變得更加清晰、簡潔,並且具有更好的組織結構,從而提高可讀性和理解難度。
- 提高可維護性:重構後的程式碼更加清晰,易於理解和修改,這有助於維護。
- 減少冗餘:重構可以刪除無用的程式碼、合併重複的程式碼和重新組織程式碼,從而減少代碼冗餘。
- 提高性能:重構可以幫助提高程式碼性能,例如通過減少循環次數和使用更高效的數據結構等。
- 改善安全性:通過重構,可以刪除容易被攻擊的程式碼,提高程式碼的安全性。
何時該重構?
重構是一個持續發生的過程,而遇到以下的狀況時,都很適合開始著手重構:
- 程式碼重複:通過重構可以消除重複的程式碼,使程式碼庫更加簡潔。
- 技術債務:隨著時間的推移,程式碼庫可能變得混亂且難以維護,導致技術債務的累積。通過改善程式碼的結構和組織,重構可以減少這種債務。
- 添加新功能:在給現有程式碼添加新功能時,重構可以確保程式碼仍然易於維護和可擴展。
- 性能優化:如果程式碼運行過慢或需要太多資源,重構可以通過解決瓶頸和低效率來提高性能。
- 錯誤修復:重構可以使得更容易找到並修復程式碼中的錯誤,同時防止新的錯誤被引入。
- 團隊合作:如果多個開發人員正在對同一程式碼庫進行工作,重構可以通過使程式碼更容易理解和維護來提高合作。
如何重構?
好的重構建議是能夠切得夠小去做,並且不影響到外部行為,這裡介紹幾個常見的技術:
Red-Green-Refactor
Red-Green-Refactor 是一種軟體開發流程,通常用測試驅動開發 (TDD),此流程分成三個步驟:
- Red(紅色):開發人員首先編寫一個失敗的測試,以驗證所需的功能不存在或不正確。
- Green(綠色):開發人員接著編寫最少的程式碼來通過測試。
- Refactor(重構):開發人員再次檢查程式碼,以確保其結構正確、可維護和易於理解。
如上圖所示,通過這種方式,開發人員可以保證程式碼符合標準,同時避免因複雜的程式碼而導致的混亂。這種方法有助於確保程式碼質量,並通過經常測試來確保程序的正確性。
抽象化(Abstraction)
如果有很多地方需要做重構,可以用抽象化(Abstraction)的方式來做類繼承、層次結構和提取,目標是減少重複且不必要得程式碼。
上圖為 Pull-Up 和 Push-Down 的方法,Pull-Up 是將方法從子類移動到父類,Push-Down 則是將方法從父類別移動到子類別。
合成方法(Composing Method)
- Extract Method:如果有一段程式碼能夠被獨立出來,則將它放到獨立的函數中,並讓函數名稱解釋該函數用途。下方有重構前後的範例。
原來的程式碼為:
void Process(MyDataSet mds) {
int result = 0;
if (mds.isReady) {
int data1 = mds.param[0];
int data2 = mds.param[1];
result = data1 % data2;
}
}
重構後的程式碼為:
void Process(MyDataSet mds){
int result = 0;
if (mds.isReady)
result = CalculateMDS(mds.param[0], mds.param[1]);
}
int CalculateMDS(int data1, int data2) {
return data1 % data2;
}
可以將不易理解的程式碼,放入新方法中,並且取一個有意義的命名,這樣可以提高可讀性和可維護性。
- Inline Method: 在函數調用的地方,直接插入函數本體,並且移除函數。下方有重構前後的範例。
原來的程式碼為:
class PizzaDelivery {
// ...
int getRating() {
return moreThanFiveLateDeliveries() ? 2 : 1;
}
boolean moreThanFiveLateDeliveries() {
return numberOfLateDeliveries > 5;
}
}
重構後的程式碼為:
class PizzaDelivery {
// ...
int getRating() {
return numberOfLateDeliveries > 5 ? 2 : 1;
}
}
如果有些函數裡面的程式碼,和函數名其實同樣的清晰易懂,就可以直接去掉函數就好。