发布在即!企业 AIGC 应用程度测评,3 步定制专属评估报告。抢首批测评权益>>> 了解详情
写点什么

重构和代码异味——通往更整洁的代码

  • 2016-09-26
  • 本文字数:2156 字

    阅读完需:约 7 分钟

重构可以让代码更整洁,更易于理解和维护。“代码异味(code smells)”的辨别需要实践和经验:设计不良的表征说明代码存在更深层次的问题。工具可以帮助我们逐步重构,并防止破坏代码。

SwanseaCon 2016 大会上,Codurance 实习生 Halima Koundi 探讨了重构和代码异味。InfoQ 正以 Q&A、综述和文章等形式对大会进行跟踪报道。

Koundi 引用了 Martin Fowler 对代码异味的定义

代码异味是一种表象,它通常对应于系统中更深层次的问题。

如果重视不够,没有适当地维护或改进代码,那么代码质量就会下降。在演讲中,Koundi 总结了不同类型的代码异味,并阐述了如何辨别它们。她提到的其中一类代码异味是“面向对象滥用”;这类异味和面向对象设计的不完全或错误实现有关。辨别“面向对象滥用”异味有助于找出可能违反面向对象设计原则、可以导致错误的对象行为的代码。

Koundi 提到的另外一类代码异味是“变更障碍”,即代码的一处变更(例如,实现一个新特性或者调整一个现有特性)会影响许多类,需要对整个代码进行大量的修改。“平行继承层次”或“发散式变更”就是这类代码异味的例子。

Koundi 演示了如何使用 Jetbrains 的 ReSharper 安全地重构代码。在演示过程中,她示范了当需要添加新的支付方法时如何调整代码。她阐述了如何逐步重构代码以及如何确保所做的变更不会破坏代码。

演讲结束后,InfoQ 采访了 Koundi,内容涉及当前存在的不同类型的代码异味、开发人员如何辨别代码异味、消除代码异味的原则、代码重构实践、开发人员如何确保所做的变更不会破坏代码、什么时候应该重构及什么时候不应该重构、重构带来的好处。

InfoQ:代码异味有哪些不同的类型?

Halima Koundi:代码异味有多种类型。部分代码异味反复出现是因为开发人员不注意以及代码库的抽象不够;这包括过长的方法、过长的参数列表等。其他的代码异味是因为面向对象原则的不完全或糟糕实现,例如,“拒绝继承(Refused Bequest)”就是这样一种异味,该情况说明我们已经引入了错误的抽象。

向系统添加噪音的代码是另外一类。例如,即使不删除,你也应该减少代码中的注释,而为方法取一个更有意义的名字。无用的代码应该删除——即使你认为稍后可能需要。

InfoQ:开发人员如何辨别代码异味?

Koundi:代码异味可以通过代码的可见特征、有形特征和无形特征来辨别。可见特征包括:过长的方法或函数体、过长的参数列表、变量多次成组出现且模式类似——这些是职责混乱抽象缺失的表征。对于有形特征,一个例子是变更需要查看并修改许多文件。无形特征是当你提出类似这样的问题,“既然我需要的行为并不相同,我为什么还要继承这个父类”。

代码异味的辨别需要实践和经验。有许多方法和套路可以帮助你实践。代码异味是表征;它们通常说明你破坏了某些设计原则。了解这些原则有助于你理解代码库的问题。

InfoQ:消除代码异味的一般原则是什么?

Koundi:重构是指改变代码的设计,而不改变代码的行为。重构是平台无关的。代码异味是糟糕设计的表征。我的建议是,读下 Martin Fowler 的著作《重构:改善既有代码的设计》。需要注意的是,重构为抽象概念并不总是正确的方式,因为那会增加系统的复杂度,而且本身可能会变成代码异味。代码有可能不是特别复杂,并不能从一定程度的抽象受益。

InfoQ:您谈了重构代码的实践并进行了演示。您能举几个例子说明下如何重构代码吗?

Koundi:我发现,有两种非常强大而又相当简单的重构方法。

  • 方法提取:假如你有一些函数,它们做了太多的事情,而你希望能够让代码更简单易读,则可以按照算法的操作步骤把算法分解,并把每个操作都提取到自己的方法中,然后根据它们的行为命名这些方法。
  • 方法重命名:表现力不够的代码难以使用。例如,你发现,在查看一个方法时,你花了 10 多分钟才弄清楚它在做什么。如果你找到了一种更好的方法来描述代码的行为,那么你应该重命名那个方法,前提是该方法没有作为一个公共 API 暴露。

就像我所演示的那样,工具和重构知识本身一样重要。了解开发环境让你可以更轻松、更迅速、更安全地执行重构。Matthew Butt 整理了一系列的重构截屏视频。他在视频中演示了如何通过简单的步骤重构代码。

InfoQ:开发人员怎么做才能确保他们正在进行的重构不会破坏代码?

Koundi:在开始重构之前,有几个方面需要确认。

  • 你可以核实系统的其他部分不受重构影响。这是通过测试完成的。
  • 关于如何使用这段代码,有一份清晰的文档。那份文档是由测试提供的。
  • 你所重构的系统部分不会遭受衰退。你猜,那是谁的工作?测试!

在重构代码之前,一定要确保自己已经有了各种测试。

InfoQ:什么时候应该重构?什么时候不应该?

Koundi:重构,像编写测试一样,应该成为同一个特性实现活动的一部分。它不是一个独立的活动。当你希望修改代码,而代码本身尚未做好变更准备时,重构它。重构是测试驱动开发(TDD)的一个重要步骤。

代码审查也是重构执行的上佳选择。

另一方面,为了实现“完美的代码”而在整个代码库上进行大量低价值的重构被称为镀金。这有损于代码整洁,因为它削弱了重构的真实性需求,盲目地为了重构而重构。如果代码正常,就不需要修改,不要碰他。

InfoQ:重构可以带来什么好处?

Koundi:重构的目标是更整洁的代码,就是说,重构旨在让代码更容易理解,降低变更成本。

查看英文原文: Refactoring and Code Smells – A Journey Toward Cleaner Code

2016-09-26 19:004597
用户头像

发布了 1008 篇内容, 共 372.3 次阅读, 收获喜欢 340 次。

关注

评论

发布
暂无评论
发现更多内容

从实际案例讲 Deno 的应用场景

keelii

Java typescript deno

腾讯人均月薪7.5w,我这是又被平均了?

程序员生活志

腾讯 职场 薪资

实践总结:在 Java 中调用 Go 代码

写代码的西瓜

分布式链路追踪Skywalking 存储模型设计

胡弦(关注公众号35岁程序员那些事)

分布式 Skywalking 高性能 分布链路追踪

统一软件开发过程(RUP)的概念和方法

雯雯写代码

Swagger 这一个文章就够了

陈磊@Criss

JavaScript中的正则表达式详解

华为云开发者联盟

Java 正则表达式 程序员 字符串 语法

如何从红蓝墨水中分离出红墨水?回声消除算法介绍

拍乐云Pano

音视频 WebRTC 回声消除 3A算法 音频技术

Maven的爱恨情仇

xcbeyond

Java maven

用Ant实现Java项目的自动构建和部署

陈磊@Criss

重磅消息,我国数字人民币将在京津冀等具备条件地区试点

CECBC

数字货币 货币

libuv 异步模型之设计概览

Huayra

libuv 异步模型

英特尔首席架构师Raja:一个“百亿亿次级计算能力惠及每个人”的时代正在到来

最新动态

Junit执行单元测试用例成功,mvn test却失败的问题和解决方法

陈磊@Criss

Facebook开源的数据Mock:Memisis详解

陈磊@Criss

实用心理学—没用你打我!

代码制造者

职场 职场搞笑 信息技术 人工

如何正确认识区块链?

CECBC

区块链价值 区块链应用

如何写出完美的接口:接口规范定义、接口管理工具推荐

xcbeyond

Java 架构 接口规范

Vue项目起步

JackWangGeek

Vue

【写作群星榜】8.1~8.14 写作平台优秀作者 & 文章排名

InfoQ写作社区官方

写作平台 排行榜 热门活动

AI能写浙江高考满分作文了!在线满分作文生成器,一键圆你满分梦

程序员生活志

AI

守护进程

书旅

php 进程 守护进程

分苹果

书旅

算法 LeetCode

PHP之闭包函数

书旅

面向对象 闭包 函数

SpringBoot系列(五):SpringBoot 日志配置(logback)

xcbeyond

Java 微服务 springboot logback

SpringBoot系列(六):SpringBoot 数据库操作(集成MyBatis)

xcbeyond

Java 微服务 mybatis springboot

MySQL中timestamp和datetime,你用的对么?

xcbeyond

MySQL 数据库 后端

NetPerf揭示容器间是高速路还是林荫小路

陈磊@Criss

应用研发平台特惠专场,助力企业加速数智化发展

移动研发平台EMAS

终于知道Kafka为什么这么快了!

大头星

kafka 消息队列

免费DDoS攻击测试工具大合集

陈磊@Criss

重构和代码异味——通往更整洁的代码_JetBrains_Ben Linders_InfoQ精选文章