zoukankan      html  css  js  c++  java
  • 学习之路三十三:重构技巧的学习

    最近看了圣殿骑士大哥的重构文章,其中有几个重构技巧让我颇有感触,特此记录下。

    文章地址:31天重构学习笔记重新整理下载

    1.封装集合,返回集合接口类型 

      这个技巧让我想起了项目中的代码,比如:

     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方法之后就可以对你的集合做任意的改动,这样的做法是非常危险的,所以必须要改进。

      重构原则:返回可迭代器类型接口来保证对集合的封装,改进如下:

     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接口

        我将在项目中运用此重构技巧。

    2.提取判断条件作为方法 - 方法名要有意义

      当遇到复杂的判断后,如果没有注释,很多人第一眼都不会理解这个判断是做什么的。

      所以把复杂的判断条件提取为方法,再取个有意义的名字,那么别人看一眼就明白做什么的,比如:

     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     }

    以同步至:个人文章目录索引

  • 相关阅读:
    查找最大回文
    java-线程池
    Java基础 IO流——第一部分
    tomcat优化
    反射
    网络编程——第二部分
    网络编程——第一部分
    Java基础 IO流——第四部分
    Java基础 IO流——第三部分
    Java基础 IO流——第二部分
  • 原文地址:https://www.cnblogs.com/yangcaogui/p/3204382.html
Copyright © 2011-2022 走看看