學習之路三十三:重構技巧的學習

最近看了聖殿騎士大哥的重構文章,其中有幾個重構技巧讓我很有感觸,特此記錄下。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     }

 

以同步至:我的文章目錄索引

相關文章
相關標籤/搜索