代码味道是经典之作。 它闻起来是因为可能有很多情况可以对其进行编辑或改进。 大多数这些气味只是一些可能出错的暗示。因此,它们本身不需要固定......(不过你应该调查一下。) 以前的代码味道 您可以在 找到所有以前的代码味道(第一部分 - XXIX) 这里 让我们继续... Code Smell 146 - 吸气评论 评论是代码的味道。吸气剂是另一种代码味道。你猜怎么了? TL;DR:不要使用吸气剂。不要评论吸气剂 问题 评论滥用者 可读性 吸气剂 解决方案 删除 getter 注释 去除吸气剂 语境 几十年前,我们习惯于对每一种方法进行评论。即使是微不足道的。 评论应该只描述一个关键的设计决策。 示例代码 错误的 pragma solidity >=0.5.0 <0.9.0; contract Property { int private price; function getPrice() public view returns(int) { /* returns the Price */ return price; } } 正确的 pragma solidity >=0.5.0 <0.9.0; contract Property { int private _price; function price() public view returns(int) { return _price; } } 检测 半自动 [x] 我们可以检测一个方法是否是一个 getter 并且有注释。 例外情况 该功能需要一个评论,这是一个偶然的吸气剂,评论与设计决策有关 标签 注释 结论 不要评论吸气剂。 它们没有增加任何实际价值并使您的代码膨胀。 关系 Code Smell 05 - 评论滥用者 Code Smell 68 - 吸气剂 Code Smell 01 - 贫血模型 学分 Reimond de Zuñiga 在 Unsplash 上拍摄的照片 代码应该非常有表现力以避免大多数评论。会有一些例外,但我们应该将评论视为“表达失败”,直到被证明是错误的。 罗伯特·马丁 软件工程名言 Code Smell 147 - 方法太多 Util 类非常适合收集协议。 TL;DR:不要在你的类中添加意外协议 问题 可读性 单一职责违规 内聚力差 高耦合 可重用性低 解决方案 打破你的课堂 提取类 重构 重构007——提取类 语境 我们倾向于将协议放在我们找到的第一个类中。 那不是问题。 我们只需要重构。 示例代码 错误的 public class MyHelperClass { public void print() { } public void format() { } // ... many methods more // ... even more methods public void persist() { } public void solveFermiParadox() { } } 正确的 public class Printer { public void print() { } } public class DateToStringFormatter { public void format() { } } public class Database { public void persist() { } } public class RadioTelescope { public void solveFermiParadox() { } } 检测 自动 [x] 大多数 linters 计算方法并警告我们。 关系 Code Smell 124 - 发散变化 Code Smell 143 - 数据块 Code Smell 94 - 进口太多 Code Smell 22 - 帮手 Code Smell 34 - 属性太多 更多信息 重构大师 标签 凝聚 膨胀裤 结论 拆分类和协议是支持小型和可重用对象的好习惯。 学分 在 上拍摄的照片 Marcin Simonides Unsplash 没有代码太大、扭曲或复杂到维护不能使它变得更糟的程度。 杰拉尔德·M·温伯格 Code Smell 148 - 待办事项 我们为未来的自己购买债务。现在是回报时间。 TL;DR:不要在代码中留下 TODO。修复它们! 问题 技术债务 可读性 信心不足 解决方案 修复你的 TODO 语境 我们在代码中遇到 TODO。我们算他们。 我们很少解决它。 我们开始欠下技术债务。 然后我们偿还债务+利息。 几个月后,我们支付的利息比原来的债务还多。 示例代码 错误的 public class Door { private Boolean isOpened; public Door(boolean isOpened) { this.isOpened = isOpened; } public void openDoor() { this.isOpened = true; } public void closeDoor() { // TODO: Implement close door and cover it } } 正确的 public class Door { private Boolean isOpened; public Door(boolean isOpened) { this.isOpened = isOpened; } public void openDoor() { this.isOpened = true; } public void closeDoor() { this.isOpened = false; } } 检测 自动 [x] 我们可以计算 TODO。 标签 技术债务 结论 我们可以计算 TODO。 大多数 linter 都会这样做。 我们需要减少它们的政策。 如果我们使用 TDD,我们会立即编写缺失的代码。 在这种情况下,TODO 仅在进行深度优先开发以记住开放访问路径时才有效。 更多信息 你应该放 ToDos 吗? 破窗理论 学分 在 上拍摄的照片 Eden Constantino Unsplash 完成项目的前 90% 后,您必须完成其他 90%。 迈克尔·亚伯拉什 Code Smell 149 - 可选链接 我们的代码更加健壮和易读。但是我们将 NULL 隐藏在地毯下。 TL;DR:避免空值和未定义。如果你避免使用它们,你将永远不需要 Optionals。 问题 空值 如果污染 解决方案 删除空值 处理未定义 语境 、Optionals、Coalescence 和许多其他解决方案帮助我们处理臭名昭著的 null。 Optional Chaining 一旦我们的代码成熟、健壮且没有空值,就没有必要使用它们。 示例代码 错误的 const user = { name: 'Hacker' }; if (user?.credentials?.notExpired) { user.login(); } user.functionDefinedOrNot?.(); // Seems compact but it is hacky and has lots // of potential NULLs and Undefined 正确的 function login() {} const user = { name: 'Hacker', credentials: { expired: false } }; if (!user.credentials.expired) { login(); } // Also compact // User is a real user or a polymorphic NullUser // Credentials are always defined. // Can be an instance of InvalidCredentials // Assuming we eliminated nulls from our code if (user.functionDefinedOrNot !== undefined) { functionDefinedOrNot(); } // This is also wrong. // Explicit undefined checks are yet another code smell 检测 自动 [x] 这是一个 。 语言功能 我们可以检测并删除它。 标签 无效的 结论 许多开发人员觉得用 null 处理污染代码是安全的。 事实上,这比根本不处理 NULL 更安全。 、 Truthy 和 Falsy 也是代码味道。 Nullish Values 我们需要瞄准更高的目标并编写更简洁的代码。 :从您的代码中删除所有空值。 好处 :使用可选链接。 坏处 :根本不处理空值。 丑陋的 关系 Code Smell 145 - 短路黑客 Code Smell 12 - 空 Code Smell 69 - Big Bang(JavaScript 可笑的转换) 更多信息 可选链接参考 无效:十亿美元的错误 如何永远摆脱烦人的 IF 哇? 学分 照片由 在 上拍摄 engin akyurt Unsplash 与怪物战斗的人可能会小心,以免自己成为怪物。如果你长时间凝视深渊,深渊也会凝视你。 尼采 Code Smell 150 - 相等比较 每个开发人员都平等地比较属性。他们错了。 TL;DR:不要导出和比较,只是比较。 问题 封装中断 代码重复 信息隐藏违规 违反 人化 拟 解决方案 在单一方法中隐藏比较 语境 我们的代码中大量使用了属性比较。 我们需要关注行为和责任。 与其他对象进行比较是对象的职责。不是我们自己的。 过早的优化器会告诉我们这是性能较低的。 我们应该要求他们提供真实的证据,并对比更易于维护的解决方案。 示例代码 错误的 if (address.street == 'Broad Street') { if (location.street == 'Bourbon St') { // 15000 usages in a big system // Comparisons are case sensitive 正确的 if (address.isAtStreet('Broad Street') { } // ... if (location.isAtStreet('Bourbon St') { } // 15000 usages in a big system function isAtStreet(street) { // We can change Comparisons to // case sensitive in just one place. } 检测 半自动 [x] 我们可以使用语法树检测属性比较。 与许多其他气味一样,原始类型也有很好的用途。 标签 封装 结论 我们需要将责任放在一个地方。 比较就是其中之一。 如果我们的一些业务规则发生变化,我们需要改变一个 。 单点 关系 Code Smell 63 - 功能羡慕 Code Smell 101 - 与布尔值的比较 Code Smell 122 - 原始痴迷 学分 在 上拍摄的照片 Piret Ilver Unsplash 行为是软件最重要的事情。这是用户所依赖的。当我们添加行为时用户会喜欢它(前提是这是他们真正想要的),但如果我们更改或删除他们依赖的行为(引入错误),他们就会停止信任我们。 迈克尔羽毛 下一篇:另外 5 种代码味道。