20 个故事,每个故事有 5 种代码气味,每个故事都是 100 种代码气味,对吧?
以前的代码气味
让我们继续...
代码气味 96 - 我的对象
你不拥有对象。
TL;DR:不要使用my作为名称前缀。
问题
- 缺乏背景
- 双射错误
解决方案
- 删除我的前缀。
- 更改为建议名称的角色。
语境
一些旧教程使用“我的”这个词作为一个懒惰的名字。这是模糊的,并导致上下文错误。
示例代码
错误的
MainWindow myWindow = Application.Current.MainWindow as MainWindow;
正确的
MainWindow salesWindow = Application.Current.MainWindow as MainWindow; /* Since window is instanciated, we are currently working with a specialized window playing a special role */
检测
- [x]自动
我们可以告诉我们的 linter 和静态检查器搜索这个前缀并警告我们。
标签
- 命名
结论
避免使用我的.对象根据使用上下文而变化。
更多信息
学分
照片由Michał Bożek在Unsplash上拍摄
想想我修改代码的经历,我发现我花在阅读现有代码上的时间比我写新代码的时间要多得多。因此,如果我想让我的代码便宜,我应该让它易于阅读。
肯特贝克
Code Smell 97 - 没有同理心的错误信息
我们应该特别注意用户(和我们自己)的错误描述。
TL;DR:使用有意义的描述并建议纠正措施。
问题
- 最小意外原则
解决方案
- 使用声明性错误消息
- 显示明确的退出操作
语境
程序员很少是 UX 专家。
我们也低估了我们可以站在柜台两边的事实。
示例代码
错误的
alert("Cancel the appointment?", "Yes", "No"); // No consequences // Options not clear
正确的
alert("Cancel the appointment? \n" + "You will lose all the history", "Cancel Appointment", "Keep Editing"); // Consequences are clear // Choice options have context
检测
- [x]手册
我们需要阅读代码审查中的所有异常消息。
标签
- 例外
- 用户体验
结论
在引发异常或显示消息时,我们需要考虑最终用户。
学分
虽然程序员从不犯错误是一个众所周知的事实,但通过在程序的关键点检查错误来取悦用户仍然是一个好主意。
罗伯特·D·施耐德
Code Smell 98 - 拼写错误
拼写和可读性对人类来说非常重要,而对机器来说并不重要。
TL;DR:照顾好你的名字。
问题
- 可读性
- 更难在代码中搜索术语。
解决方案
- 拼写检查您的代码。
- 使用带有拼写检查的 IDE
语境
我们中的许多人不会说英语作为我们的第一语言。
我们需要特别注意我们的文本和名称。
这篇文章的标题中有一个错字作为上下文的证明,也是一个点击诱饵😀
示例代码
错误的
comboFeededBySupplyer = supplyer.providers();
正确的
comboFedBySupplier = supplier.providers();
检测
标签
- 可读性
- 命名
- 代码样式
结论
密切注意你的名字。
几个月后,您可能会成为阅读代码的人。
关系
更多信息
学分
每一个写得好的大程序里面都有一个写得好的小程序。
汽车霍尔
代码气味 99 - 第一秒
我们看到多少次惰性参数名称?
TL;DR:根据角色而不是偶然位置命名你的论点
问题
- 可读性
- 意图透露姓名
解决方案
- 使用有意义的名称
语境
在编写方法时,我们通常不会停下来寻找像样的名字。
我们也从不重构显而易见的东西。
示例代码
错误的
class Calculator: def subtract(self, first, second): return first - second class CalculatorTest def test_multiply(): assert equals(first, second)
正确的
class Calculator: def subtract(self, minuend, subtrahend): return minuend - subtrahend class CalculatorTest def test_multiply(): assert equals(expectedValue, realValue)
检测
- [x]手册
我们可以警告诸如“第一”和“第二”之类的禁止词作为参数名称。
标签
- 可读性
结论
始终遵循规则建议参数。
根据角色命名您的合作者。
关系
更多信息
学分
照片由Priscilla Du Preez在Unsplash上拍摄
最终的源代码是真正的软件设计。
杰克·里维斯
代码气味 100 - GoTo
GOTO 在 50 年前被认为是有害的
TL;DR:永远不要使用 GoTo。
问题
- 可读性
- 难以遵循的代码
解决方案
- 用结构化代码替换GOTO
- 使用例外
语境
我开始用 Basic 编程。
GOTO 在那里被严重滥用。
我必须在康复模式下从头开始学习结构化编程。
示例代码
错误的
for x < 0 { if x > -1e-09 { goto small } z = z / x x = x + 1 } for x < 2 { if x < 1e-09 { goto small } z = z / x x = x + 1 } if x == 2 { return z } x = x - 2 p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6] q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7] return z * p / q small: if x == 0 { return Inf(1) } return z / ((1 + Euler*x) * x) }
正确的
for x < 0 { if x > -1e-09 { return small(x, z) } z = z / x x = x + 1 } for x < 2 { if x < 1e-09 { return small(x, z) } z = z / x x = x + 1 } if x == 2 { return z } x = x - 2 p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6] q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7] return z * p / q small(x, z) { if x == 0 { return Inf(1) } return z / ((1 + Euler*x) * x) } }
检测
- [x]自动
在支持GOTO的语言中,我们的 linter 可以警告我们不要使用它。
标签
- 可读性
结论
我们在几十年前就承认了 GOTO 问题。
这个问题仍然存在于 GoLang、PHP、Perl 等现代语言中。
大多数程序员幸运地避免了 GOTO 语句。下一个目标是考虑有害的null 使用。
礼貌XKCD
关系
更多信息
学分
詹斯·约翰森 ( Jens Johnsson)在Unsplash上拍摄的照片
向之前接触过 BASIC 的学生教授好的编程实际上是不可能的:作为潜在的程序员,他们在精神上被残缺不全,没有再生的希望。
埃兹格·迪克斯特拉
这就是现在的全部内容,我们已经达到了 100 个里程碑。
下一篇文章将解释另外 5 种代码异味!