code smell

转自:http://www.nowamagic.net

Code Smell中文译名一般为“代码异味”,或“代码味道”,它是提示代码中某个地方存在错误的一个暗示,开发人员可以通过这种smell(异味)在代码中追捕到问题。

在计算机编程社区中,code smell代表了任何标志着事物变坏的征兆。它常常标志代码应该被refactored或者全部的设计都应该被reviewed。这个短语出现在 WardsWiki上,它是被Kent Beck杜撰出来的。在refactoring兴起之后,这个短语的使用率骤增。

判断是否存在code smell经常是主观判断,并且随着语言、开发者、开发理论的不同而存在差异。

经验丰富和知识渊博的开发人员通过对优秀设计有一种“感觉”,他们已经达到一种称之为“无意识能力 (UnconsciousCompetence)”的状态。也就是说,他们无需思考,只要通过查看代码或一段设计就可以立马对这个项目的代码质量有一种 “感觉”,能够对代码设计的优劣有一个大致的判断。

但大家需要注意,code smell只是一种“暗示”,而非一种“确定”。将某些事物称之为“code smell”并未是一种攻击,它只是一种提示:开发人员需要对项目设计进行更进一步的查看。因此,code smell更多是“直觉的,本能的”。

code smell一般包括:

  1. Duplicated Code。代码重复几乎是最常见的异味了。他也是Refactoring 的主要目标之一。代码重复往往来自于copy-and-paste 的编程风格。与他相对应OAOO 是一个好系统的重要标志。
  2. Long method。它是传统结构化的“遗毒”。一个方法应当具有自我独立的意图,不要把几个意图放在一起,特别注意大类和长方法。
  3. Large Class。大类就是你把太多的责任交给了一个类。这里的规则是One Class One。
  4. Divergent Change。一个类里面的内容变化率不同。某些状态一个小时变一次,某些则几个月一年才变一次;某些状态因为这方面的原因发生变化,而另一些则因为其他方面的原因变一 次。面向对象的抽象就是把相对不变的和相对变化相隔离。把问题变化的一方面和另一方面相隔离。这使得这些相对不变的可以重用。问题变化的每个方面都可以单 独重用。这种相异变化的共存使得重用非常困难。
  5. Shotgun Surgery。这正好和上面相反。对系统一个地方的改变涉及到其他许多地方的相关改变。这些变化率和变化内容相似的状态和行为通常应当放在同一个类中。
  6. Feature Envy。对象的目的就是封装状态以及与这些状态紧密相关的行为。如果一个类的方法频繁用get 方法存取其他类的状态进行计算,那么你要考虑把行为移到涉及状态数目最多的那个类。
  7. Data Clumps。某些数据通常像孩子一样成群玩耍:一起出现在很多类的成员变量中,一起出现在许多方法的参数中……,这些数据或许应该自己独立形成对象。
  8. Primitive Obsession。面向对象的新手通常习惯使用几个原始类型的数据来表示一个概念。譬如对于范围,他们会使用两个数字。对于Money,他们会用一个浮点数来表示。因为你没 有使用对象来表达问题中存在的概念,这使得代码变的难以理解,解决问题的难度大大增加。好的习惯是扩充语言所能提供原始类型,用小对象来表示范围、金额、 转化率、邮政编码等等。
  9. Switch Statement。基于常量的开关语句是OO 的大敌,你应当把他变为子类、state 或strategy。
  10. Parallel Inheritance Hierarchies。并行的继承层次是shotgun surgery 的特殊情况。因为当你改变一个层次中的某一个类时,你必须同时改变另外一个层次的并行子类。
  11. Lazy Class。一个干活不多的类。类的维护需要额外的开销,如果一个类承担了太少的责任,应当消除它。
  12. Speculative Generality。一个类实现了从未用到的功能和通用性。通常这样的类或方法唯一的用户是test case。不要犹豫,删除它。
  13. Temporary Field。一个对象的属性可能只在某些情况下才有意义。这样的代码将难以理解。专门建立一个对象来持有这样的孤儿属性,把只和他相关的行为移到该类。最常见的是一个特定的算法需要某些只有该算法才有用的变量。
  14. Message Chain。消息链发生于当一个客户向一个对象要求另一个对象,然后客户又向这另一对象要求另一个对象,再向这另一个对象要求另一个对象,如此如此。这时,你需要隐藏分派。
  15. Middle Man。对象的基本特性之一就是封装,而你经常会通过分派去实现封装。但是这一步不能走得太远,如果你发现一个类接口的一大半方法都在做分派,你可能需要移去这个中间人。
  16. Inappropriate Intimacy。某些类相互之间太亲密,它们花费了太多的时间去砖研别人的私有部分。对人类而言,我们也许不应该太假正经,但我们应当让自己的类严格遵守禁欲主义。
  17. Alternative Classes with Different Interfaces。做相同事情的方法有不同的函数signature,一致把它们往类层次上移,直至协议一致。
  18. Incomplete Library Class。要建立一个好的类库非常困难。我们大量的程序工作都基于类库实现。然而,如此广泛而又相异的目标对库构建者提出了苛刻的要求。库构建者也不是万能的。有时 候我们会发现库类无法实现我们需要的功能。而直接对库类的修改有非常困难。这时候就需要用各种手段进行Refactoring。
  19. Data Class。对象包括状态和行为。如果一个类只有状态没有行为,那么肯定有什么地方出问题了。
  20. Refused Bequest。超类传下来很多行为和状态,而子类只是用了其中的很小一部分。这通常意味着你的类层次有问题。
  21. Comments。经常觉得要写很多注释表示你的代码难以理解。如果这种感觉太多,表示你需要Refactoring。
时间: 2024-10-13 12:48:15

code smell的相关文章

Top 6 Refactoring Patterns to Help You Score 80% in Code Quality

Top 6 Refactoring Patterns to Help You Score 80% in Code Quality Posted by Ajitesh Kumar / In Code Review, Software Quality / January 31, 2014 Have done several code reviews in past and found following top 5 code smells common across most of these co

手把手教你写个AOP框架

Why AOP? AOP(Aspect-Oriented Programming),意思是面向切面编程.传统的OOP面向对象相当于站在一个上帝模式从上往下看,里面的一块块都是一个对象,由我任意组合:而AOP不同之处在于,他是以一个旁观者的身法,从"侧面"看整个系统模块,看看哪里可以见缝插针,将自己想要处理的一段义务逻辑编制进去. Code duplication is the ultimate code smell. It's a sign that something is very

软件工程第四次作业

1.敏捷开发是在什么样的背景下产生的?其主要特点有哪些?什么时候选择敏捷开发更恰当,为什么? 2.Code smell 是如何产生的?有哪些典型的 code smell?代码重构(Code refactoring)有哪些优点?有哪些代码重构的方法? 1.答:敏捷软件开发产生的背景: 敏捷这个词汇最早于2001年被一些热衷于改善软件开发过程的软件工程师用来描述一种能够增加客服满意度的软件开发过程--敏捷式开发过程. 1.2其主要特点有哪些? (1)敏捷开发方法是“适应性”(Adaptive)而非“

第四次作业(1,2)

问题: 1.敏捷开发是在什么样的背景下产生的?其主要特点有哪些?什么时候选择敏捷开发更恰当,为什么? 2.Code smell 是如何产生的?有哪些典型的 code smell?代码重构(Code refactoring)有哪些优点?有哪些代码重构的方法? 解答:    1. 背景:  敏捷开发是在基于客户能够在需求阶段就给出完整.准确的需求的假设,所以期望于在项目初期获得详细的需求,然后严格控制需求变更,最终完成符合需求的软件.但实际上需求是“涌现”出来的,而无法再项目初期就明确的定义它,也就

第四次作业(第1,2题)

题目: 1.敏捷开发是在什么样的背景下产生的?其主要特点有哪些?什么时候选择敏捷开发更恰当,为什么? 2.Code smell 是如何产生的?有哪些典型的 code smell?代码重构(Code refactoring)有哪些优点?有哪些代码重构的方法? 1.答:敏捷软件开发产生的背景: •软件开发的新挑战 a:快速的市场进入时间,要求高生产率 b:快速变化的需求 c:快速发展的技术 •传统的软件开发方法 a:强调过程和文档 b:对变化的适应能力偏弱 敏捷软件开发的特点:敏捷开发存在优先级,是

二进制世界建造者 编程格言

1.保持简单直白(Keep It Simple Stupid) 2.不要自我复制(Don't Repeat Yourself) 3.能干的人解决问题.智慧的人绕开问题(A clever person solves a problem. A wise person avoids it)– Einstein 4.沉默会被理解为赞同(Silence is construed as approval)( Picked from Kevin blog ) 我什么都没看见!没看见! "破窗理论"与

通过github提升自己-测试反馈、持续精进

如果我们仅仅是将自己的代码commit.push到github上,那么对于我们的技术不会有太多的提升.我们所做的仅仅只是将github当成了我们的网盘. 我们每发布一个版本的时候,是不是也就意味着给用户一个新的版本--持续交付. 敏捷软件开发 显然我是在扯淡,这和敏捷软件开发没有什么关系.不过我也不知道瀑布流是怎样的.说说我所知道的一个项目的组成吧: 看板式管理应用程序(如trello,简单地说就是管理软件功能) CI(持续集成) 测试覆盖率 代码质量(code smell) 对于一个不是远程的

构建之法——现代软件工程

1.敏捷开发是在什么样的背景下产生的?其主要特点有哪些?什么时候选择敏捷开发更恰当,为什么?            答:产生的背景:在书上P113页有说到背景.在互联网时代,大部分的服务是通过网络服务器端实现,在客户端有各种方便的推送给渠道.一般消费者成为主要用户.网络的传播速度和广度,使得知识的获取变得更加容易,很多软件服务可以由一个小团队来实现.同时,技术更新的速度在加快,那种一个大型团队用一种成熟技术开发2-3在发布软件的时代已经过去了.用户需求变化也在加快,开发流程必须跟上这些快速变化的

第四次软件工程作业

1.敏捷开发是在什么样的背景下产生的?其主要特点有哪些?什么时候选择敏捷开发更恰当,为什么? 敏捷开发产生的背景:从20世纪70年代到90年代提出并使用的许多软件开发方法都试图在软件构思.文档化.开发和测试的过程中强加某种形式的严格性. 在20世纪90年代后期,一些抵制这种严格性的开发人员系统地阐述了他们自己的原则,试图强调灵活性在快速有效的软件生产中所发挥的作用.他们将他 们的思想整理为“敏捷宣言”. 主要特点:1. 工作在小的团队中    2. 团队是跨功能的-包括测试人员,开发人员,文档开