重構的好處不多敘述了,大家都明白,好的代碼不僅可讀性強,重用性強,而且可維護性高。書上論述的非常詳細,我挑選幾種最常用的重構方法,並用C#語言做示例,總結一下,學習一下!
1:提取函數
原始代碼為:
static void Main(string[] args) { User user = new User(); user.name = "張三"; user.age = 12; PrintOwing(user); Console.ReadKey(); } public static void PrintOwing(User user) { PrintDetail(); Console.WriteLine("姓名:" + user.name); Console.WriteLine("年齡:" + user.age); } private static void PrintDetail() { }
重構為:
static void Main(string[] args) { User user = new User(); user.name = "張三"; user.age = 12; PrintOwing(user); Console.ReadKey(); } public static void PrintOwing(User user) { PrintBanner(); PrintUserInfo(user); } public static void PrintUserInfo(User user) { Console.WriteLine("姓名:" + user.name); Console.WriteLine("年齡:" + user.age); } private static void PrintBanner() { }
思想:讓每個函數只做一件事,抽取能夠被組織在一起的代碼,並單獨抽取為一個函數。如果函數的粒度小,被復用的機會就更大。后期如果需求改動,那么需要修改的代碼就很少,可維護性高,同時閱讀起來也不清晰。
2:內聯臨時變量
原始代碼:
double orderInfo = anOrder.BasePrice(); return (orderInfo > 1000);
重構為:
return (anOrder.BasePrice() > 1000);
注意:重構前要保證這個臨時變量只被賦值一次,所以當遇到循環語句時,要注意被內聯的變量的值是否會在循環中被改變。有時在執行循環之前定義固定的臨時變量是必要的。尤其是當臨時變量取自某對象的屬性,而這個對象將在for循環中被更改。
3:以查詢取代臨時變量
原始代碼:
double GetBasePrice = quantity * itemPrice; if(GetBasePrice > 10) { return GetBasePrice * 9.5; } else { return GetBasePrice * 9.8; }
重構為:
if(GetBasePrice() > 10) { return GetBasePrice() * 16.2; } else { return GetBasePrice() * 16.1; } ... double GetBasePrice() { return quantity * itemPrice; }
4:以衛語句嵌套條件表達式
原始代碼:
double GetPayAmount() { double result; if(_isDead) result = deadAmount(); else { if(_isSeparated) { result = separatedAmount(); } else { if(_isRetired) { result = retiredAmount(); } else { result = normalPayAmount(); } } } return result; }
重構為:
double GetPayAmount() { if(_isDead) { return deadAmount(); } if(_isSeparated) { return separatedAmount(); } if(_isRetired) { return retiredAmount(); } return normalPayAmount(); }
在初學編程的時候,很多人都會寫出很多if…else嵌套的代碼,其實很多時候,else並不是必須的。關於if…else…如何取決,關鍵看你對各分支的重視程度
注:這是在一篇博客里學到的,地址忘記了!
5::引入解釋性變量
原始代碼:
if((platform.ToUpper().IndexOf("MAC") > -1) && (browser.ToUpper().IndexOf("IE") > -1) && wasInitialized() && resize > 0) { // }
重構為:
bool isMacOs = platform.ToUpper().IndexOf("MAC") > -1; bool isIE = browser.ToUpper().IndexOf("IE") > -1; bool wasResized = resize > 0; if(isMacOs && isIE && wasInitialized() && wasResized) { // do something }
在某些情況下,表達式可能非常的復雜以至於難以閱讀。這樣,臨時變量可以幫助你將表達式分解為比較容易管理的形式。
6:流程控制語句簡化
原始代碼:
int row = DbHelperSql.ExecuteSql(sql); if(row> 1) { return true; } else { return false; }
重構為:
int row = DbHelperSql.ExecuteSql(sql); if(row) > 1 { return true; } return false; ///// int row = DbHelperSql.ExecuteSql(sql); return (row > 1); return DbHelperSql.ExecuteSql(sql) > 1;