《重构,改善既有代码的设计》读书笔记二:代码的坏味道

什么样的代码应该被重构

  • 重复代码(Duplicate Code)

   如果你在一个以上的地方看到相同程序结构,那么可以肯定:将其合而为一程序会变得更好。

   以下列举一些大家在代码中常见的Duplicate Code

  • 同一个类的不同函数含有相同的表达式

       如果发现在同一个类中的不同函数中存在相同的表达式,这时候就需要采用Extract Method提炼出重复代码,然后在需要使用的地方去调用被提炼出的那段代码即可。

  • 两个互为兄弟的子类内含有相同的表达式

       遇到这种情况,只需要对这两个子类都采用Extract Method提炼出重复的代码,再将其放入到父类中。如果代码之间只是类似,并非完全相同,那么将相同的部分运用Extract Method将相同的部分提取构成单独一个函数。如果是两个毫不相关的类中出现Duplicate Code,考虑将重复代码提炼到一个独立的类中,然后在其他类中使用这个新类的函数。总之,决定这个被提取出的函数放在什么位置最合适,只要保证它被安置后不会再在其他任何地方再次重复出现即可。

  • 过长的函数(Long Method)

    过长的函数会带来很多的问题:程序越长越难理解,无法被有效的进行复用等。所以,建议你应该更积极的去分解函数。我们遵循这样一条原则:每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立函数中,并以其用途来命名函数。
     
  • 过大的类(Large Class)

       如果想利用单个类做太多的事情,其内部往往就会出现太多实例变量,一旦如此,Duplicate Code也就可能接踵而至了。对此,你可           以通过Extract Class将几个变量一起提炼到新类内。提炼时应该选择类内彼此相关的变量,将他们放在一起。

  • 过长的参数列(Long Parameter List)

    太长的参数列往往难以理解,太多参数会造成前后不一致、不易使用,而且一旦你需要更多的数据,就不得不修改它。如果将对象传递给函数,大多数据修改都将没有必要,因为你很可能只需(在函数内)增加一两条请求就能得到更多的数据。至于参数列中最多放几个参数不算过长,每个软件公司可能会有自己的一套规范,比如我所在的公司要求最长不能超过5个。
     
  • 发散式变化(Divergent Change)

        我们希望软件能够容易被修改(毕竟软件再怎么说本来就该是“软”的)。一旦需要修改,我们希望能够跳到系统的某一点,只在该处          修改而不会牵连到其他多处的跟随修改。如果不能做到这点,你可能就要考虑代码重构了。举个例子来说,如果某个经常因为不用的          原因在不同的方向上发生变化,Divergent Change就出现了。当你看着一个类说:“如果新加入一个数据库,我必须修改这三个函                数;  如果新出现一种金融工具,我必须修改这四个函数。”那么此时也许将这个对象分成两个会更好,这么一来每个对象就可以只因         一种变化而需要修改,这种拆分方式也正好符合“单一职责”的要求,针对某一外界变化的所有相应修改都只应该发生在一个类中。

        

  • 散弹式修改(Shotgun Surgery)

       如果每遇到某种变化,你都必须在许多不同的类内做出许多小修改,你所面临的就是Shotgun Surgery。如果需要修改的代码散布在程序四处,你不但很难找到他们,也很容易忘记某个重要的修改。Divergent change和Shotgun Surgery的区别是:Divergent change是指一个类受多种变化的影响,Shotgun Surgery则是一种变化则引发多个类相应的要做修改。这两种情况下都希望对代码进行重构,是“外界变化”与“需要修改的类”趋于一一对应。

  • 冗赘类(Lazy Class)

       项目中创建的每个类都应该有它存在的价值,当重构以后使他身形缩水,不在做那么多工作;或者开发者在开发代码前为了应对未来的某些潜在的变化而添加的一些类,但实际上这些变化并没有发生。不论是上述哪种原因,这些类应该被cut掉。因为所有的程序代码后期都是要去运维的,对于这些Lazy Class来说增加里系统代码的复杂度,造成系统更难理解和维护,进而增加了运维成本(spend more money),得不偿失。
 

  • 暂时字段(Temporary Field)


有时候代码中会有这样的对象:期内某个实例变量仅仅是为了某种特定情况而设。这样的代码让人不易理解,因为通常情况大家会认为对象在所有时候其内部的所有属性都应该是被需要的。如果一个类中有个复杂的算法,需要好几个变量,由于实现着不希望传递一长串参数,所以他把这些参数都放进字段中。但是这些字段只有在使用该算法的时候才有效,其他情况下只会让人迷惑。对于这种情况,可以考虑单独建一个类,把这些变量和相关函数提炼进来。
 

  • 过多的注释(More Comments)

        代码注释在很多时候是很必要的,它可以让程序代码的读者更容易对代码进行理解。但是常常会有这样的情况:你看到一段代码有着很长的注释,然后发现,这段注释之所以存在是因为代码很糟糕。如果你需要用注释来解释一段代码要做什么,那么可以考虑对这段代码进行重构,完成重构之后你也许会发现这段长长的注释已经变得多余了,因为你的代码已经很清楚的说明了一切,足以让其他人在不需要这些注释的情况也能理解。当你感觉需要撰写注释时,请先尝试重构,试着让所有的注释变得多余。
 

     以上列举出来的代码中的“坏味道”有时候也不是那么绝对的,需要在代码开发中去不断的体会去琢磨,到底什么样的代码需要重构,需要我们不断的去探索去实践。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值