Martin Fowler在Refactoring: Improving the Design of Existing Code(中译名:《重构——改善既有代码的设计》)一书中与Kent Beck一起总结了22种代码坏味(Bad Smells in Code),因为Sunny这段时间正在做一些与代码味道自动识别与自动重构有关的研究工作,对这些内容进行了重新的深入理解与分析。后续将在博客中转载和原创一些相关的文章,希望对广大从事软件开发的朋友们能够带来些许帮助。你在编程过程中面临哪些代码味道?哪些代码味道你觉得最应该消除?对于消除这些代码味道你有何意见和建议?欢迎大家与我一起交流讨论。

注:本文中,代码坏味道的中文名称源于侯捷和熊节的中译本《重构——改善既有代码的设计》。

      类内味道

      1、Measured Smells(可度量的味道)

  (1) Long Method(过长方法)

A method is too long.(方法太长。)

        (2) Large Class(过大类)

A class is trying to do too much, it often shows up as too many instance variables.(一个类试图做太多的事情,通常会出现太多的实例变量。)

       (3) Long Parameter List(过长参数列)

A method needs passing too many parameters.(一个方法需要传递太多的参数。)

       (4) Comments(过多的注释)

Do not write comments when it is unnecessary. When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous.(在非必要的情况下不要写注释。当你觉得需要去写一段注释时,你首先应该尝试去重构代码,这将使任何注释都变得是多余的。)

      2、Unneccessary Complexity(不必要的复杂性)

       (5) Speculative Generality(夸夸其谈的未来性)

If a machinery was being used, it would be worth it. But if it is not, it is not. The machinery just gets in the way, so get rid of it.(如果一个装置【一个设计或实现方案】会被用到,那就值得去做;如果用不到,就不值得。用不到的装置会成为拦路石,因此需要将它搬移。)

      3、Duplication(重复)

       (6) Duplicated Code(重复代码)

Same code structure happens in more than one place.(在一个以上的地方发现相似的代码结构。)

       (7) Alternative Classes with Different  Interfaces(异曲同工的类)

Classes are doing similar things but with different signatures. (不同的类做相同的事情,却拥有不同的签名,主要是指方法签名不同。)

      4、Conditional Logic(条件逻辑)

       (8) Switch Statements(Switch惊悚现身)

Switch statements often lead to duplication. Most times you see a switch statement which you should consider as polymorphism.(Switch语句通常会导致代码重复。大多数时候,一看到Switch语句你应该考虑使用多态来替换。)

     类间味道

     1、Data(数据)

       (9) Primitive Obsession(基本类型偏执)

Primitive types are overused in software. Small classes should be used in place of primitive types in some situations.(在软件中,基本类型被过度使用。在某些场合下,应该使用一些小的类来代替这些基本类型。)

       (10) Data Class(纯稚的数据类)

These are classes that have fields, getting and setting methods for the fields, and nothing else. Such classes are dumb data holders and are almost certainly being manipulated in far too much detail by other classes.(这些类拥有一些字段【成员变量】,并提供了对应的Getter和Setter方法,除此以外一无所有。这些类只是一些不会说话的数据容器, 而且它们必定会被其他类过分琐细地操作。)

       (11) Data Clumps(数据泥团)

Some data items together in lots of places: fields in a couple of classes, parameters in many method signatures.(一些数据项同时出现在多个地方:例如一对类中的值域【成员变量】,多个方法签名中的参数等。)

       (12) Temporary Field(令人迷惑的暂时值域)

Sometimes you see an object in which an instance variable is set only in certain circumstances. Such code is difficult to understand, because you expect an object to need all of its variables.(有时候你会看到一个对象的实例变量仅为某些特定的场合而设。这样的代码将导致难以理解,因为你期望一个对象需要它所有的变量。)

     2、Inheritance(继承)

       (13) Refused Bequest(被拒绝的遗赠)

Subclasses get to inherit the methods and data of their parents, but they just use a few of them.(子类继承父类的方法和数据,但是它们只需要使用其中的一部分。)

       (14) Inappropriate Intimacy(狎昵关系)

Sometimes classes become far too intimate and spend too much time delving in each others’ private parts.(有时候,类之间的关系变得非常亲密,并且需要花费大量时间来探究彼此之间的私有成分。)

       (15) Lazy Class(冗赘类)

Each class you create costs money to maintain and understand. A class that is not doing enough to pay for itself should be eliminated.(你所创建的每个类都需要花钱去维护和理解。一个类如果不值其身价,它就应该消失。)

      3、Responsibility(职责)

       (16) Feature Envy(依恋情节)

The whole point of objects is that they are a technique to package data with the processes used on that data. A Feature Envy is a method that seems more interested in a class other than the one it actually is in.(对象的全部要点在于它是一种封装数据以及施加于这些数据的处理过程的技术。依恋情节是指一个方法对别的类的兴趣高过它本身所在的类。)

       (17) Message Chains(过度耦合的消息链)

You see message chains when a client asks one object for another object, which the client then asks for yet another object, which the client then asks for yet another object, and so on. Navigating in this way means that the client is coupled to the structure of the navigation. Any change to the intermediate relationships causes the client to have to change.(你看到的消息链是这样的:当一个客户端向一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象,如此反复。这种方式的导航意味着客户端将与整个导航结构紧密耦合在一起。一旦对象之间的联系发生任何改变,将导致客户端也不得不做出相应的修改。)

       (18) Middle Man(中间转手人)

You look at a class’s interface and find that half the methods are delegating to this other class. It may mean problems.(当你审查一个类的接口时发现其中有一半的方法都委托给了其他类,这也许就意味着存在问题了。)

     4、Accommodating Change(协调变化)

       (19) Divergent Change(发散式变化)

Divergent change occurs when one class is commonly changed in different ways for different reasons.(如果某个类经常因为不同的原因在不同的方向上发生变化就会产生发散式变化。也就是说,一个类拥有多个引起它发生变化的原因。)

       (20) Shotgun Surgery(霰弹式修改)

Shotgun surgery is similar to divergent change but is the opposite. Every time you make a kind of change, you have to make a lot of little changes to a lot of different classes.(霰弹式修改与发散式变化类似,却又存在相反的一面。每次进行某种修改时,你都必须对多个不同的类进行很多对应的小修改。)

       (21) Parallel Inheritance Hierarchies(平行继承体系)

Parallel inheritance hierarchies is really a special case of shotgun surgery. In this case, every time you make a subclass of one class, you also have to make a subclass of another. You can recognize this smell because the prefixes of the class names in one hierarchy are the same as the prefixes in another hierarchy.(平行继承体系是霰弹式修改的一个特例。在这种情况下,当你为某个类增加一个子类时,你不得不为另一个类也相应增加一个子类。你也许能够识别到这种味道,因为一个继承体系中类的类名前缀与另一个体系中的类名前缀一样。)

     5、Library Classes(库类)

       (22) Incomplete Library Class(不完善的程序库类)

Library classes should be used carefully, especially we do not know whether a library is completed.(库类在使用时一定要小心,特别是在我们不知道一个库是否完整时。)

<转载> 22种代码味道(Martin Fowler与Kent Beck) http://blog.csdn.net/lovelion/article/details/9301691的更多相关文章

  1. AutoFac控制反转 转载https://blog.csdn.net/u011301348/article/details/82256791

    一.AutoFac介绍 Autofac是.NET里IOC(Inversion of Control,控制反转)容器的一种,同类的框架还有Spring.NET,Unity,Castle等.可以通过NuG ...

  2. (转载)RTMP协议中的AMF数据 http://blog.csdn.net/yeyumin89/article/details/7932585

    为梦飞翔   (转载)RTMP协议中的AMF数据 http://blog.csdn.net/yeyumin89/article/details/7932585 这里有一个连接,amf0和amf3的库, ...

  3. 线段树详解 (原理,实现与应用)(转载自:http://blog.csdn.net/zearot/article/details/48299459)

    原文地址:http://blog.csdn.net/zearot/article/details/48299459(如有侵权,请联系博主,立即删除.) 线段树详解    By 岩之痕 目录: 一:综述 ...

  4. Mui本地打包笔记(一)使用AndroidStudio运行项目 转载 https://blog.csdn.net/baidu_32377671/article/details/79632411

    转载 https://blog.csdn.net/baidu_32377671/article/details/79632411 使用AndroidStudio运行HBuilder本地打包的Mui项目 ...

  5. 基于eclipse的mybatis映射代码自动生成的插件http://blog.csdn.net/fu9958/article/details/7521681

    基于eclipse的mybatis映射代码自动生成的插件 分类: JAVA 数据库 工具相关2012-04-29 00:15 2157人阅读 评论(9) 收藏 举报 eclipsegeneratori ...

  6. 数组中&a与&a[0]的区别 转载自http://blog.csdn.net/FX677588/article/details/74857473

    在探讨这个问题之前,我们首先来看一道笔试题,如下: [摘自牛客网]下列代码的结果是:(正确答案是 C) main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)( ...

  7. Win32消息循环机制等【转载】http://blog.csdn.net/u013777351/article/details/49522219

    Dos的过程驱动与Windows的事件驱动 在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别: DOS程序主要使用顺序的,过程驱动的程序设计方法.顺序的,过程驱动的程序有一个 ...

  8. matlab 降维工具 转载【https://blog.csdn.net/tarim/article/details/51253536】

    降维工具箱drtool   这个工具箱的主页如下,现在的最新版本是2013.3.21更新,版本v0.8.1b http://homepage.tudelft.nl/19j49/Matlab_Toolb ...

  9. MVC和WebApi 使用get和post 传递参数。 转载https://blog.csdn.net/qq373591361/article/details/51508806

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq373591361/article/details/51508806我们总结一下用js请求服务器的 ...

随机推荐

  1. 虚拟机中安装centOS及破解nuke的方法

    跟the foundry的工程师邮件交流,我的一个Nuke脚本在对方机器上执行有问题,确认对方是centOS之后我决定在自己机器上安装一个centOS来找一下问题所在.安装重点如下: 一: 一定要下载 ...

  2. XBOX360更新游戏封皮(FSD自制系统)

    第一步,请记下上图左下角的IP地址第二步,打开电脑IE浏览器,输入“第二步”你记下的IP地址“回车”然后,就如下图所示了. 输入账号:f3http 密码:f3http 进入,然后你就进到你的360 F ...

  3. PHP操作mongoDB 笔记

    转自 http://blog.csdn.net/black_ox/article/details/22678747 命令也可以在参考http://www.jb51.net/article/51601. ...

  4. linux找不到动态链接库 .so文件的解决方法

    linux找不到动态链接库 .so文件的解决方法 如果使用自己手动生成的动态链接库.so文件,但是这个.so文件,没有加入库文件搜索路劲中,程序运行时可能会出现找不到动态链接库的情形. 可以通过ldd ...

  5. Android 中Jackson的简单使用

    第一步:下载Jackson的jar包http://pan.baidu.com/s/1qXHwtQ0 第二步:在gradle中导入jar包 第三步:创建ObjectMapper对象的单例 Jackson ...

  6. vue 数据绑定 绑定属性 循环渲染数据

    <template> <!-- vue的模板里面 所有的内容要被一个根节点包含起来 --> <div id="app"> <h2>{ ...

  7. C,Java,C#数据类型对比总结

  8. js中基本数据类型和引用数据类型的区别

    1.基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型. 基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构成的对象. 当我们把变量赋值给一个变 ...

  9. php删除字符串最后一位

    一.前言 从数据库中select()读取一对多的信息时,经常需要将取出的数组用某个特定的字符分割,然后拼接成字符串. 常见的语法格式: foreach ($arr as $key => $val ...

  10. 超详细Redis数据库入门教程

    [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 – 简介8.redis ...