hrmai

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

       园子里面好像已经有很多关于重构的文章了,但是好像并没有多少是对应用中的终结。最近我也在重构一个项目,我也总结一下我自己的经验吧。

       我重构并没有园子里面大部分文章中做的那么好,他们是从整个系统架构上进行重构,而我只是优化一下代码的结构而已。

       我不知道有多少人看过600+行的函数(非初始化界面),我这次遇到的基本上都是这样的函数,600+行的代码,加上7-8层的IF(while,for)嵌套,看起来真的很痛苦。我的重构方法大致如下:

   1、减少if嵌套层数

   减少if嵌套其实有一个很好的方法,把一些可以结束方法的条件放在前面(参考代码大全)比如这样的一段代码:

 

 if(条件1){
  。。。
  }
else{ 
    。。。
    
return
  }
  。。。
   
return


  我们可以将else里面的内容提到前面去,这样我们就少了一个层嵌套,如下:

  

if(!条件1){
    .....
    
return;
  }
  .......
  
return;


    2、提取重复代码为函数

  在一个很长的函数中重复代码是一个很严重的问题,所以在减少了嵌套层数之后,我们就应该将重复代码提取成为函数。这里我举一个我重构中看到的最简单的例子:

  

string xmlContent="<xml width=\""+width.ToString()+"\"   heigth=\""+heigth.ToString()+"\"></xml>"


  其中width和heigth在不同的代码块中有不同的计算方式。这时我把它提取成了一个函数:

  

InitXmlContent(int width,int heigth)


  这样做一个好处就是我们不会把相同的代码散布到类里面不同的地方去。其实最简单的例子应该是martin flower 在企业架构模式里面举的那个例子,名字拼接,如果你在程序里面写了很多次lastname.firstname的拼接,那么如果到时候要改为firstname.lastname时你要改多少地方。但是如果你将它独立为一个方法了呢?其实这里的重复代码只是最简单的重复代码提取,有部分重复代码是逻辑一样,但是参数不一样,这样的代码提取我现在只做到了看懂程序,再提取 。如果有高人有好的方法,请指教。

  3、将可以看成是独立功能的代码块提取为函数

  其实这里看起来和上面的有点像,但是却又不一样,上面注重的是减少重复代码,优化以后的维护,但是这里注重的是优化程序结构。在提取函数的时候我们可以是用vs2008的提取方法的功能,这个功能可以让我们看到函数需要的输入参数。在提取方法的时候一个一定要注意的就是要为方法取一个好名字,这样以后看代码的人才不会像你现在骂人那样骂你。这里的提取可以以一个逻辑分支为一个方法,这样程序看起来比较简单划一。当然如果你的程序过长也可以将可以独立的代码块提取为方法。现在可能有人质疑前面的话了,为什么可以提取为方法的独立代码块不提取为方法?我个人的见解是这样的。虽然很多高人说过,函数不应该超过5行。但是我个人觉得,程序最好不要超过20行,加上try catch之类的不要超过30行,要不然你就要想一下你的方法是不是有太多的职责了。但是如果你的函数已经比较短小精干了,那么也就没有必要在去分函数了,那么可能就显得过度了。

  4、 使用#region预处理指令

  有时候对于那些几百行的函数,而且又有很负载的逻辑,那么我一般是使用#region来分块。分块的标准是构成一个独立功能的代码块。这样可以让你注意力集中在一个地方。更容易理解代码块本身的含义。其实刚开始的时候可能也没办法分块,因为我们不知道程序的结构是怎么样的,这时,我一般的做法是找到return语句,将return其作用的代码块作为一个块。

  5、多次重构

  很多时候我们在重构的时候都会发现一些代码块如果提取为函数这个函数还是会很大,可能会有50~60行(我试过将一个200行的代码块提取为函数),这时我们应该将这个代码块提取为函数之后再进行进一步的优化,毕竟我们的大脑是有限的,不可能记得住那么复杂的逻辑。

  6、处理复杂的逻辑判断

  如果一个逻辑判断很复杂,那么我们可以采取两种方法,一:使用多个逻辑变量的逻辑运算来代替逻辑判断;二、使用方法来封装逻辑判断。

   7、重命名方法内部的局部变量

  这里我推荐大家将一些很奇异的局部变量名字重命名,这样当我们再看这个函数的时候你就会明白这个变量是做什么的。毕竟我们不会只看这个函数1,2次。

  8、删除全局变量

  我一直都不推荐是用全局变量,除非这个变量被声明为static。如果重构的类中有这样的变量,建议你删除掉,取而代之的是在方法中增加一个参数可以使用(ref)。

   这是我对上个月的重构工作的总结,如果你有什么见解也请分享一下,共同进步。

posted on 2010-05-07 00:09  Leon Mai  阅读(1958)  评论(10编辑  收藏  举报