最近看了聖殿騎士大哥的重構文章,其中有幾個重構技巧讓我很有感觸,特此記錄下。html
文章地址:31天重構學習筆記從新整理下載post
1.封裝集合,返回集合接口類型 學習
這個技巧讓我想起了項目中的代碼,好比:ui
1 public class Check 2 { 3 private List<Detail> _details = new List<Detail>(); 4 5 public IList<Detail> GetDetails() 6 { 7 return _details; 8 } 9 } 10 11 public class Detail 12 { 13 public string Name { get; set; } 14 }
若是這樣設計,那麼用戶經過調用GetDetails方法以後就能夠對你的集合作任意的改動,這樣的作法是很是危險的,因此必需要改進。this
重構原則:返回可迭代器類型接口來保證對集合的封裝,改進以下:url
1 public class Check 2 { 3 private List<Detail> _details = new List<Detail>(); 4 5 private Dictionary<int, Detail> _specificDetail = new Dictionary<int, Detail>(); 6 7 public IEnumerable<Detail> GetDetails() 8 { 9 return _details; 10 } 11 12 public IEnumerable<KeyValuePair<int, Detail>> GetSpecificDetail() 13 { 14 return _specificDetail; 15 } 16 } 17 18 public class Detail 19 { 20 public string Name { get; set; } 21 }
迭代器文章入口:迭代器學習之一:使用IEnumerable和IEnumerator接口spa
我將在項目中運用此重構技巧。設計
2.提取判斷條件做爲方法 - 方法名要有意義code
當遇到複雜的判斷後,若是沒有註釋,不少人第一眼都不會理解這個判斷是作什麼的。htm
因此把複雜的判斷條件提取爲方法,再取個有意義的名字,那麼別人看一眼就明白作什麼的,好比:
1 public class Check 2 { 3 public Detail GetDetail { get; set; } 4 5 public void SendMessage() 6 { 7 //這樣的判斷別人根本不知道是幹什麼的 8 if (GetDetail != null && GetDetail.Number > 0) 9 { 10 //Send Message 11 } 12 13 //重構後的代碼 14 //這樣別人就知道這個判斷的做用:判斷當前的信息有沒有提交 15 if (HasConfirm(GetDetail)) 16 { 17 //Send Message 18 } 19 } 20 21 public bool HasConfirm(Detail detail) 22 { 23 return GetDetail != null && GetDetail.Number > 0; 24 } 25 } 26 27 public class Detail 28 { 29 public int Number { get; set; } 30 }
3.爲帶有大量bool參數的方法從新進行拆分組合
這個重構手法在項目中尚未用過,方法帶有大量的bool參數原本就很奇葩,不過若是真的遇到了,咱們也有應對方法,以下:
1 public class Test 2 {
//若是是這樣的一個方法,你知道它是幹什麼的嗎,根本就不能理解它的用意 3 private void Create(bool isA, bool isB, bool isC) 4 { } 5 }
重構後的代碼:
1 public class Test 2 { 3 //進行拆分後在從新組合 4 public void CreateA() 5 { 6 this.Create(true, false, false); 7 } 8 9 public void CreateB() 10 { 11 this.Create(false, true, false); 12 } 13 14 public void CreateC() 15 { 16 this.Create(false, false, true); 17 } 18 19 private void Create(bool isA, bool isB, bool isC) 20 { } 21 }
4.避免雙重否認
其實這個重構手法我理解爲儘可能避免使用在if條件裏使用 - 「!」.
由於若是原本你的判斷條件就是表達否認的意思,那麼在加上一個否認的判斷,那麼就會是雙重否認。
那別人理解起來是否是會很抓狂,他會在心理畫個圈圈狠狠的詛咒你的,:-),好比:
1 public class Test 2 { 3 public void TestOne() 4 { 5 //原本想表達已經付款了,因此只能加個否認來判斷咯 6 //但是這個交別人理解起來真的很抓狂 7 if (!NoPayment) 8 { 9 //TO DO 10 } 11 } 12 13 public bool NoPayment { get; set; } 14 }
重構後的代碼:
1 public class Test 2 { 3 public void TestOne() 4 { 5 //原本想表達已經付款了,因此只能加個否認來判斷咯 6 //但是這個交別人理解起來真的很抓狂 7 if (!NoPayment) 8 { 9 //TO DO 10 } 11 12 //重構後的代碼 13 //避免使用雙重否認來做爲判斷條件 14 if (HasPayment) 15 { 16 17 } 18 } 19 20 public bool NoPayment { get; set; } 21 22 public bool HasPayment { get; set; } 23 }
5.儘快返回 - 返回值
這個重構技巧能夠分解複雜的判斷條件,是那些冗餘的判斷分支化成簡介的小分支,好比:
1 public class TestOne 2 { 3 private List<Detail> _details; 4 5 public void Display() 6 { 7 //這麼一大長串的判斷條件是否是很噁心 8 if (_details != null) 9 { 10 if (_details.Count > 0) 11 { 12 foreach (var item in _details) 13 { 14 if (item.Number > 0) 15 { 16 //TO DO 17 } 18 } 19 } 20 } 21 } 22 } 23 24 public class Detail 25 { 26 public int Number { get; set; } 27 }
重構後的代碼:
1 public class TestOne 2 { 3 private List<Detail> _details; 4 5 public void Display() 6 { 7 //重構以後是否是很清爽呀 8 //哈哈 9 if (_details == null || _details.Count <= 0) 10 return; 11 foreach (var item in _details.Where(p => p.Number > 0).Select(p => p)) 12 { 13 //TO DO 14 } 15 } 16 } 17 18 public class Detail 19 { 20 public int Number { get; set; } 21 }
以同步至:我的文章目錄索引