代码的坏味道之一——译自《重构》

重复代码

    臭味集合里面排第一的就是重复代码了。如果你在不止一处发现了同样结构的代码,你可以确定如果你找到一种方法来统一他们的话,你的程序将会改善。

    最简单的重复代码问题是当你在同一个类中有两个方法有相同的表达时出现的。那么你需要做的所有步骤只是提取方法然后在两处调用代码。

    另一种常见的重复问题是当你在两个兄弟类中有相同的表达。你可以通过在两个类中提取方法然后拉升方法(Pull up Method)来消灭重复。如果这段代码相似但不相同,你需要通过提取方法来分离相同和不同的部分。你可能会发现你可以使用构成模版方法(Form Template Method)。如果这些方法是在用不同的算法做同样的事情,你可以选择两种算法中比较清楚的那个然后替换算法。

   如果你的重复代码在两个不相关的类中,考虑在一个类中使用提取类,然后在另一个类中使用这个新部件。另一种可能是这个方法只属于其中一个类,并且要被其他类调用;或者方法属于另一个类需要参考原始类。你必须决定这个方法在哪更有意义,并且确认他只在那里不在其他任何地方。

长方法

    对象程序存在的最好最长的都是那些短方法组成的。新接触对象的程序员经常觉得对象程序是无尽的委托,没有一点计算发生。当你和这样的程序相处一些年份,你会学到小方法是多么的有价值。所有间接带来的好处——解释,分享,选择都被小方法支持。

    早在编程最初时期人们就意识到一段流程越长就越难被理解。老一些的语言对子程序的调用付出更多的代价,阻止了人们接触小方法。现代面对对象语言差不多消除了进程中的调用的代价。对于代码的读者仍然还有代价,就是如果要看子程序做了什么需要切换内容。开发环境允许同时看两个方法帮助消除了这个代价,但真正让理解小方法更容易的是好的命名。如果对一个方法你有好的名字,那么你就不需要看他的方法体了。

    网络效应即你应该在分解方法上更积极一些。一个我们遵循的启示是,当我们觉得需要注释的时候,我们写一个方法来取代之。这样的一个方法包含被注释过的代码,但被以代码的意图命名了,而不是代码怎样做命名。我们可能对几行代码这样做,也可能只针对一行。我们这样做即使我们调用的方法比他代替的代码还要长,但提供的方法名解释代码的意图。这里的关键不是方法的长度,而是方法做什么和怎么做之间的语义距离。

    百分之九十九的时候,简短方法你所需要做的全部就是提取方法。把方法中看起来很适合在一起的部分找到,然后作为一个新的方法。

    如果你有一个许多参数和临时变量的方法,这些元素碍了提取方法的事。如果你试图提取方法,你以传递那么多参数和临时变量作为提取方法的参数收尾,那么这个结果几乎不比原来的状况可读性更高。你常常可以通过用请求替代临时变量来消除临时变量。一长列参数可以被引入参数对象和保留整个对象(Preserve Whole Object)来精简。

    如果你尝试了并且你仍然有许多临时变量和参数,那么是时候使用重型火炮:用方法对象替代方法了。

    你怎么鉴别需要被提取的代码块呢?一个好的技巧是寻找注释。注释常常是这类语义距离的信号。一块带有注释的代码告诉你,这段代码做的事可以被基于这个注释命名的方法替代。即使是一行代码也值得提取,如果它需要解释。

    条件语句和循环也是提取的信号。用分解条件语句来处理条件语句表达。对待循环,提取循环和循环中的代码到他们自己的方法里去。

        

代码的坏味道之一——译自《重构》

时间: 2024-10-10 19:37:11

代码的坏味道之一——译自《重构》的相关文章

代码的坏味道之五 ——译自《重构》

夸夸其谈未来性Speculative Generality Brian Foote 为一个我们都很敏感的味道建议的名字.你会遇到它当有人说“哦,我认为我们某一天会需要能力去做那一类的事”然后这样一来希望得到各种钓钩和特别的例子去处理并不需要的事情.结果往往是更难懂也难维护.如果所有的这些机制被用上,那这样做还是值得的.如果不是这样,也就不值得.这个机制就是这样产生的,所以处理掉它. 如果你有抽象类并没有做很多事,用Collapse Hierarchy.不必要的委托可以用Inline Class去

代码的坏味道之三——译自《重构》

散弹式修改(Shotgun Surgery) 散弹式修改和发散式变化类似,但却相反.每当你做一种修改你却必须对很多不同的类做很多小的变化,你面临的就是散弹式修改.当变化到处都是时,有的变化就不好找到了,这样很容易漏掉重要的更改. 这种情况下你要使用移动方法(Move Method)和移动字段(Move Field)来把所有的变化放到一个类里.如果没有现成的类合适,就创建一个类.通常你会用到内联化类(Inline Class)把一系列行为放到一起.你会有一点发散式变化的问题,但你可以轻松处理它.

代码的坏味道之四 ——译自《重构》

基本类型偏执Primitive Obsession 大多数编程环境有两种类型的数据.记录类型允许你把数据结构化成有意义的集合.基本类型是你建设用的砖块.记录类型总是会产生一定量的额外开销.这可能是数据库中的表,或者被很尴尬的创建当你希望他们只为一或两件东西存在. 关于对象一个很有意义的东西是,他们模糊甚至打破了基本类型和大型类之间的界线.你可以很轻松的写小的无法和语言中内建类型相区别的类.Java对数字有基本类型,但字符和日期这些在其他环境也是基本类型的,在Java里是类. 新接触对象的人通常不

代码的坏味道之二——译自《重构》

巨型类 当一个类尝试做的太多,它常常展示出过多的实例变量.当一个类有太多实例变量,重复代码的出现就不远了. 你可以提取类来打包一部分变量.选择在部件中有意义的变量放在一起.例如,“存款总量”和“存款货币”很可能在同一部件中.更宽泛的说,在一个类中变量的某个子集共同的前缀和后缀预示着组成同一个部件的机会.如果这个部件有成为子类的意义,你会发现提取子类往往更容易. 有时一个类不会一直使用它全部的实例变量.如果如此,你可能可以提取类或者提取子类若干次. 相比于一个类有太多实例变量,一个类有太多代码是重

重构摘要3_代码的坏味道

如果尿布臭了,就换掉它. 1.Duplicated Code 重复代码 Extract Method Pull Up Method Form Template Method --> Template Method 模式 Substitute Algorithm --> 函数算法替代 2.Long Method 过长的函数 "间接层"所带来的全部利益--解释能力.共享能力.选择能力--都是有小函数支持的. 真正关键在于一个好名字. 每当感觉需要以注释来说明点什么的时候,我们就

重构笔记——代码的坏味道(上)

在重构入门篇中,简单地介绍了重构的定义.为何重构.何时重构等.我想对于重构是如何运作的,你已经有了较好的理解了.但是对于代码中的坏味道,你可能 知道的并不多.坏味道可能是无形中产生的,也可能是开发人员偷懒造成的,还可能是其它某些因素导致的.不管怎么样,代码中的坏味道对程序没有半点好处,它 会促使程序腐烂,甚至变质.对于开发人员,真的是很有必要对这些坏味道进行了解和熟悉,理解它们产生的场景.针对当前程序,发现坏味道,对代码进行重构, 以消除坏味道,提高代码质量,提高自己水平. 下面让我们一起来熟悉

实例说明什么是代码的坏味道,如何重构

所谓优雅的代码,或者恶心的代码,很多时候是见仁见智的.也同时是看个人喜好或者习惯的.当经验不足,看的和写的代码还不够多的时候,我们可能会追捧某个大神或者奉某本经典为圭臬.然后跟学校的学弟们说,有空多看看<重构>和<设计模式>吧. 在我看来,优雅的代码并不是说这个代码写的有多神,多么让人惊叹.能够让人清晰的去阅读去理解就是好的代码.代码并不是艺术,更多的是严谨的表达出自己的思路.在这个过程中代码的易读性是第一位的,然后是正确性,然后是运行效率. 让人感到恼火的代码也并一定是写的多么凌

关于重构(四)--代码的坏味道

代码的坏味道主要有: Duplicated Code---(重复的代码):如果你在两个以上的地点看到相同的程序结构,那可以:设法将它们合二为一,程序会变得更好. Long Method ------(过长函数): 1 private void bindSaleInfo(string swhere) 2 { 3 ArrayList proList = getProductInfo(swhere); 4 string colorStr = ""; 5 StringBuilder rowHt

代码的坏味道【4】

返回总目录 十四.Temporary Field(令人迷惑的暂时字段) 1.某个实例变量仅为某种特定的情况而设 2.某些实例字段仅为某个函数的复杂算法少传参数而设 将这些变量和相关函数提炼到一个独立的类中. 十五.Message Chains(过度耦合的消息链) 如果你看到用户向一个对象请求另一个对象,然后再向后者请求另一个对象,然后在请求另一个对象……这就是消息链. 实际代码就是一长串的getThis()或者一长串临时变量. 使用隐藏“委托关系”(这个后面会讲)来进行重构.当然了,可以在消息链