paint-brush
如何找到代码中有问题的部分 [第 XXX 部分]经过@mcsee
629 讀數
629 讀數

如何找到代码中有问题的部分 [第 XXX 部分]

经过 Maximiliano Contieri9m2023/01/23
Read on Terminal Reader

太長; 讀書

代码有异味,因为可能有很多情况可以对其进行编辑或改进。大多数这些气味只是暗示可能有问题。评论是一种代码气味。吸气剂是另一种代码味道。不要评论吸气剂。它们没有增加任何实际价值并使您的代码膨胀。
featured image - 如何找到代码中有问题的部分 [第 XXX 部分]
Maximiliano Contieri HackerNoon profile picture

代码味道是经典之作。

它闻起来是因为可能有很多情况可以对其进行编辑或改进。


大多数这些气味只是一些可能出错的暗示。因此,它们本身不需要固定......(不过你应该调查一下。)

以前的代码味道

您可以在这里找到所有以前的代码味道(第一部分 - XXIX)


让我们继续...


Code Smell 146 - 吸气评论

评论是代码的味道。吸气剂是另一种代码味道。你猜怎么了?


TL;DR:不要使用吸气剂。不要评论吸气剂

问题

  • 评论滥用者
  • 可读性
  • 吸气剂

解决方案

  1. 删除 getter 注释
  2. 去除吸气剂

语境

几十年前,我们习惯于对每一种方法进行评论。即使是微不足道的。


评论应该只描述一个关键的设计决策。

示例代码

错误的

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:不要在你的类中添加意外协议

问题

  • 可读性
  • 单一职责违规
  • 内聚力差
  • 高耦合
  • 可重用性低

解决方案

  1. 打破你的课堂
  2. 提取类

重构

重构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 SimonidesUnsplash上拍摄的照片


没有代码太大、扭曲或复杂到维护不能使它变得更糟的程度。

杰拉尔德·M·温伯格


Code Smell 148 - 待办事项

我们为未来的自己购买债务。现在是回报时间。


TL;DR:不要在代码中留下 TODO。修复它们!

问题

  • 技术债务
  • 可读性
  • 信心不足

解决方案

  1. 修复你的 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 仅在进行深度优先开发以记住开放访问路径时才有效。

更多信息

学分

Eden ConstantinoUnsplash上拍摄的照片


完成项目的前 90% 后,您必须完成其他 90%。

迈克尔·亚伯拉什


Code Smell 149 - 可选链接

我们的代码更加健壮和易读。但是我们将 NULL 隐藏在地毯下。


TL;DR:避免空值和未定义。如果你避免使用它们,你将永远不需要 Optionals。

问题

解决方案

  1. 删除空值
  2. 处理未定义

语境

Optional Chaining 、Optionals、Coalescence 和许多其他解决方案帮助我们处理臭名昭著的 null。


一旦我们的代码成熟、健壮且没有空值,就没有必要使用它们。

示例代码

错误的

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 更安全。


Nullish Values 、 Truthy 和 Falsy 也是代码味道。


我们需要瞄准更高的目标并编写更简洁的代码。


好处:从您的代码中删除所有空值。


坏处:使用可选链接。


丑陋的:根本不处理空值。

关系

Code Smell 145 - 短路黑客

Code Smell 12 - 空

Code Smell 69 - Big Bang(JavaScript 可笑的转换)

更多信息

无效:十亿美元的错误

如何永远摆脱烦人的 IF

哇?

学分

照片由engin akyurtUnsplash上拍摄


与怪物战斗的人可能会小心,以免自己成为怪物。如果你长时间凝视深渊,深渊也会凝视你。

尼采


Code Smell 150 - 相等比较

每个开发人员都平等地比较属性。他们错了。


TL;DR:不要导出和比较,只是比较。

问题

  • 封装中断
  • 代码重复
  • 信息隐藏违规
  • 违反人化

解决方案

  1. 在单一方法中隐藏比较

语境

我们的代码中大量使用了属性比较。


我们需要关注行为和责任。


与其他对象进行比较是对象的职责。不是我们自己的。


过早的优化器会告诉我们这是性能较低的。


我们应该要求他们提供真实的证据,并对比更易于维护的解决方案。

示例代码

错误的

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 IlverUnsplash上拍摄的照片


行为是软件最重要的事情。这是用户所依赖的。当我们添加行为时用户会喜欢它(前提是这是他们真正想要的),但如果我们更改或删除他们依赖的行为(引入错误),他们就会停止信任我们。

迈克尔羽毛


下一篇:另外 5 种代码味道。