前言

在日常生活中,当我们买的水果放久了之后会发出一种难闻的气味(“坏味道”),这个时候我们就应该把它扔掉。同样,代码也有“坏味道”,当然确定什么是和不是代码“坏味道”是主观的,它会随语言、开发人员和开发方法的不同而不同。在工作当中,很多时候都是在维护之前的项目和在此基础上增加一些新功能,为了能让项目代码易于理解和维护,要时刻注意代码中的“坏味道”,当发现代码如果有坏味道了,要及时去重构它使其变成优秀的整洁的代码。本文列举代码中一些常见的“坏味道”和相应的重构方案。

过长方法 (Long Method)

这种“坏味道”表现为方法代码行数过长,方法行数越长,就越难以理解和维护它。一个比较有用的方案就是当你觉得需要对方法中的内容加注释的时候,你应该将这个代码段作为一个新方法提取出来,哪怕有时候仅仅是一行代码也可以这么做,而且方法的命名要尽量做到见名知意,如果局部变量和参数干扰到方法的提取,则可以使用引入参数对象来进行提取。一般情况下,方法中条件运算符和循环是可以将代码移至单独方法的一个很好的代码段,对于条件运算符,可以尝试分解条件,如果方法出现循环,可以尝试提取方法。

过大的类 (Large Class)

这种“坏味道”表现为一个定义了很多的变量、方法代码行数很长的大类,刚开始的时候类通常都不“大”,一段时间之后,随着业务的发展新功能的增加,类通常都会就会变得越来越“大”,通常程序员都喜欢在原有的类上添加属性或者添加新的方法的方式来完成功能的开发,当一个类的代码行数过多或者功能职责过多的时候,就意味着我们应该将其拆分了,常用有以下三种不同的拆分方式:

提取新类,当大类的部分行为可以分解为一​​个单独的组件,则可以使用提取类的方式拆分。

提取子类,当大类的部分行为可以以不同的方式实现或在极少数情况下使用,则可以使用提取子类方式拆分。

提取接口,当有必要列出客户端可以使用的操作和行为的列表的时候,则可以提取接口的方式拆分。

通过重构大类,可以使开发人员无需记住一个类的大量属性,在许多情况下,将大类分成多个部分可以避免代码和功能的重复。

过长参数列表 (Long Parameter List)

这种“坏味道”表现为一个方法超过三个以上的参数,当一个方法合并了几个算法之后就会可能出现过多参数的情况,这些参数用来控制方法将要运行哪种算法以及如何运行的。长参数列表也可能是由于我们将类的对象创建过程拆分产生的,想象这么一个场景,当我们把用于创建方法所需对象的代码片段从方法内部移至用于调用方法的代码,然后创建的对象作为参数传入方法,这样,原始类就不再了解对象之间的关系,依赖性降低了。当有多个这种对象需要创建之后,每个对象将需要自己的参数,这意味着参数列表会更长。随着时间的流逝,我们就会越来越难于理解这种方法的长参数列表的具体含义了,清除这种“坏味道”的方式就是将方法的参数列表封装成一个对象的属性。通过重构之后,可以使代码的可读性更高,代码更简短,同时可能还会让你看到以前未被注意的重复代码。

过多注释 (Too Many Comments)

这种“坏味道”表现为一种方法充满解释性的注释,当开发者意识到自己的代码不直观或不明显时一般都会给代码加上相应的注释。写代码注释的意图通常都是好的,是为了可以有更好的可读性让后面易于维护,在这种情况下,代码注释就会掩盖了可以改进的可疑代码的“坏味道”,好的方法名或者类名就是最好的注释。

>The best comment is a good name for a method or class.

当我们遇到没有注释就无法理解代码片段时,首先应该尝试以无需注释的方式更改代码结构,解决过多注释通常有以下几种方式:

提取变量,当如果要使用注释来解释复杂的表达式的时候,则可以使用“提取变量”的方式将表达式拆分为可理解的子表达式。

提取方法,当如果注释解释了一段代码片段,则可以通过提取方法的方式来将这一部分变成一个单独的方法,这个时候往往方法的名称就是注释的内容。

通过提取变量或者提取方法的方式可以使代码变得更加直观和明显。

Switch 滥用(Switch Abuse)

这种“坏味道”表现为代码中存在一个复杂的 switch 运算符,通常,if 条件语句的代码可以分散在程序中的不同位置,当需要添加新条件后,就必须找到所有开关代码并进行修改。根据经验,当看到 switch 时,你第一时间应该想到要用多态性去重构代码。如果 switch 是基于类型判断的,可以使用“用子类替换”或“用状态/策略替换”。但是当运算符中没有太多条件,并且它们都使用不同的参数调用相同的方法,那么多态其实是多余的。在这种情况下,则可以使用“将参数替换为方法”,然后将该方法分解为多个较小的方法,并相应地更改 switch ,代码经过重构之后改进其的组织方式。当然如果 switch 操作只是执行简单的判断时,则没有必要进行代码重构。还有就是,在工厂设计模式(工厂方法和抽象工厂)使用开关运算符来选择创建的类时,也没有必要对其进行重构。

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

这种“坏味道”表现为两个类有着相同的功能,但方法名称不同,产生这种代码的原因通常是创建其中一个类的程序员可能并不知道功能上等效的类已经存在。清除这种“坏味道”有以下几种方式:

方法重命名,重命名相同功能的方法,使它们在所有替代类中相同。

移动方法、添加参数和泛型方法使得方法的签名和实现相同。

如果仅仅是重复了方法的部分功能,可以使用提取相同父类的方式重构,在这种情况下,现有的类将成为该父类的子类。

通过重构异曲同工类后,可以去除掉不必要的重复代码,从而减少代码的行数,同时代码也会有更好的可读更易于理解。

临时变量滥用(Temporary Field)

这种“坏味道”表现为一些临时变量仅在某些情况下才获得其值,在这些情况之外,它们都为空,通常,当我们在创建一个算法后需要定义一些临时变量以供该算法输入使用。此时,程序员往往会决定在类中为此算法去创建变量,而不是在方法中创建大量参数,导致这些变量仅在算法当中才会使用,其它地方都不会使用这些变量。一个应对的方式就是将这些临时变量和对其进行操作的所有代码都提取出来放到单独的类中。

重复代码(Duplicate Code)

这种“坏味道”表现为两个或者多个代码片段看起来几乎相同,当我们多个人同时在同一项目中的不同部分上工作时,通常就会发生复制,产生重复的代码。因为正在实现不同的功能,因此可能并不知道其他人已经编写了类似的代码,这些代码其实是可以根据自己的需要进行复用的。当代码中的一些特定部分看起来不同但实际上实现相同的功能时,这样的代码有着更多细微的重复,这种情况下的代码重复可能很难找到和修复。如果重复代码在两个处于相同层次结构的子类出现时,我们可以通过以下方式进行重构:

提取方法,将重复的代码片段提取为方法然后放到共同的父类当中。

如果重复的代码在构造方法内部,则将其提取到父类的构造方法当中去,然后再在当前类的构造方法中使用 super 的方式调用父类构造方法。

如果重复的代码结构上相似但又不完全相同,那么则使用模板方法方式重构。

如果重复代码在两个或者多个不同的类出现时,我们可以通过以下方式进行重构:

如果这些类不是层次结构的一部分,可以使用提取共同父类的方式来为这些类创建一个保留所有之前的功能的单个父类。

当很难或者不可能创建父类,那么可以在其中的任意一个类中使用提取类的方式来重构,然后在其它类中使用刚刚创建出来的类。

通过重构合并重复的代码可以简化代码的结构并使其更加简短和易于后期维护。

总结

本文总结了一些代码中常见的“坏味道”并给出了一些解决方法,重构是需要我们开发人员时刻都要去做的,要将重构始终贯穿在整个开发过程中,不断去发现代码中的“坏味道”,不断的持续的渐进重构。最后不管我们是如何去重构代码的,其背后的指导思想都是 Solid 原则。

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[代码中的坏味道]http://www.zyiz.net/tech/detail-122548.html

java 代码坏味道_代码中的坏味道相关推荐

  1. 如何应对java服务器宕机_代码中如何应对缓存服务器宕机的情况

    今天在演练这样一个场景--假如所有缓存服务器都宕机,而且不能很快恢复,并且假设数据库服务器能够支撑,在代码中如何应对这样的情况? 之前的做法是在读缓存的地方捕获异常并写入日志,然后直接从数据库读取数据 ...

  2. java 代码书写规范_代码书写规范和命名规范

    上一篇给大家分享了一下,关于文档编写的几个概念.这篇文章阐述如果编写代码书写规范以及命名规范文档.[以java语言为例] 1.代码书写规范 代码书写规范,能够让不同的人,写出相同风格的代码.很多人都看 ...

  3. java五子棋代码详解_代码详解:Java和Valohai的深度学习之旅

    全文共10735字,预计学习时长22分钟或更长 有一款生命周期管理工具(也称云服务)叫做Valohai,它有着友好的用户界面和简洁的布局设计. 许多有关Valohai的案例和文档都是基于Python和 ...

  4. java 代码整洁快捷方式_代码整洁之道:你的代码是否足够优雅、整洁、易懂?...

    普通的工程师堆砌代码,优秀的工程师优雅代码,卓越的工程师简化代码.如何写出优雅整洁易懂的代码是一门学问,也是软件工程实践里重要的一环.下面从注释.命名.方法,并发等视角简单给出了部分最佳实践.相信每一 ...

  5. python代码自动格式化_代码的自动格式化

    代码格式化是一个在软件开发过程中值得一提的话题. 所谓代码格式化就是说,程序员在书写代码的过程中或者完成代码开发后对代码书写格式排版的调整,使得已经完成的代码变的更美观整洁也更具有可读性,也能增加完成 ...

  6. linux nand 坏块_Nand Flash 中的坏块(Bad Block)

    Nand Flash 中,一个块中含有 1 个或多个位是坏的,就称为其为坏块 Bad Block. 坏块的稳定性是无法保证的,也就是说,不能保证你写入的数据是对的,或者写入对了,读 出来也不一定对的. ...

  7. java代码重构工具_代码重构什么意思 Java代码重构的几种模式

    指对软件代码做任何更动以增加可读性或者简化结构而不影响输出结果. 软件重构需要借助工具完成,重构工具能够修改代码同时修改所有引用该代码的地方.在极限编程的方法学中,重构需要单元测试来支持. 在软件工程 ...

  8. js中当等于最小值是让代码不执行_网页中JS函数自动执行常用三种方法

    本文为大家分享了在网页中JS函数自动执行常用方法,供大家参考,具体内容如下 一.JS方法 1.最简单的调用方式,直接写到html的body标签里面: 2.在JS语句调用: function myfun ...

  9. java 查询线程池_[代码全屏查看]-我的 Java 线程池测试类

    [1].[代码] TestThreadPool.java package net.oschina.tester; import java.io.Serializable; import java.ut ...

最新文章

  1. Nagios(一)——LAMP 环境搭建
  2. 服务器安装lnmp的时候出现client_loop: send disconnect: Connection reset by peer
  3. 按键精灵post教程_掌控POST(1)
  4. SPSS答疑解惑25问【SPSS 071期】
  5. OpenMP和Pthread比较
  6. Linux进程间通信(2)信号量
  7. 记七彩虹刷bios问题
  8. 慧翔PMP培训及感想
  9. 怎么调节台式计算机字体大小,电脑上怎么调整字体大小
  10. 计算机开机后屏幕和键盘不亮,电脑开机显示器不亮键盘也不亮怎么回事
  11. Jenkins 汉化
  12. 微信小程序GET请求总,如果参数中出现'+ ',' '加号符号,发送到后台会出现空格
  13. 沈阳计算机维修,联想电脑维修站查询_沈阳维修电脑_东莞维修电脑
  14. 易飞ERP客户问题集合之一
  15. 容器网络连接被重置?这篇文章教你如何去定位及分析
  16. Linux查看系统资源信息
  17. adb命令——上传和下载文件
  18. yum安装ruby_Ruby 安装 – Linux | 菜鸟教程
  19. 论文笔记(三十):Counter-Hypothetical Particle Filters for Single Object Pose Tracking
  20. C语言求1到50的数的三次方的和。

热门文章

  1. PAC模式和全局模式的优缺点对比
  2. PowerMILL 2016汽车零件模具编程加工视频教程
  3. springboot No qualifying bean of type
  4. python爬虫教程:爬虫时如何知道是否代理ip伪装成功
  5. crontabat命令用法举例
  6. linux 查看crond服务器,CentOS安装crond服务
  7. java队列火车厢重排_火车车厢重排——队列实现
  8. 计算器算贝塞尔公式_怪物猎人:近战技能收益计算器Ver.4打死不改版
  9. php开启opcache
  10. Unity3d 学习与应用之 DEBUG