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

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

经过 Maximiliano Contieri8m2023/01/10
Read on Terminal Reader

太長; 讀書

代码味道只是一些可能出错的提示。大多数这些气味本身不需要固定。 (不过,你应该研究一下。)你可以找到所有以前的代码味道(第一部分 - XXVIII)[在这里。](https://hackernoon.com/the-one-and-only-software-design-principle -1x983ylp)
featured image - 如何找到代码中有问题的部分 [第 XXIX 部分]
Maximiliano Contieri HackerNoon profile picture

代码味道是经典。

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


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

以前的代码味道

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


让我们继续...


Code Smell 141 - IEngine、AVehicle、ImplCar

你在野外见过 IEngine 吗?


TL;DR: 不要给你的类添加前缀或后缀

问题

  • 可读性
  • 双射故障
  • 实施名称

解决方案

  1. 删除前缀和后缀
  2. 以它们的作用命名你的对象

语境

某些语言具有与数据类型、抽象类或接口相关的文化习俗。这些名称为我们的模型加载了难以理解的认知翻译。


我们必须亲吻

示例代码

错误的

public interface IEngine { void Start(); } public class ACar { } public class ImplCar { } public class CarImpl { }

正确的

public interface Engine { void Start(); } public class Vehicle { } public class Car { }

检测

  • [x]自动

如果我们有同义词库,我们可以指出难懂的名字。

例外情况

在 C# 中,将“I”放在接口名称中是一种常见的做法,因为如果没有它,您将无法分辨它是接口还是类。


这是一种语言气味。

标签

  • 命名

结论

为您的模特使用真实姓名。

关系

代码味道 130 - AddressImpl

更多信息

学分

Tim Mossholder 在 Unsplash 上拍摄的照片


有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。


杰米扎文斯基

软件工程名言


Code Smell 142 - 构造函数中的查询

在域对象中访问数据库是一种代码味道。在构造函数中执行它是一种双重气味。


TL;DR:构造函数应该构造(并可能初始化)对象。

问题

解决方案

  1. 将基本业务逻辑与意外持久性分离。
  2. 在持久性类上,在构造函数/析构函数之外的函数中运行查询。

语境

在遗留代码中,数据库没有正确地与业务对象分开。


构造函数不应该有副作用。


根据单一职责原则,他们应该只构建有效的对象

示例代码

错误的

public class Person { int childrenCount; public Person(int id) { childrenCount = database.sqlCall("SELECT COUNT(CHILDREN) FROM PERSON WHERE ID = " . id); } }

正确的

public class Person { int childrenCount; // Create a class constructor for the Main class public Person(int id, int childrenCount) { childrenCount = childrenCount; // We can assign the number in the constructor // Accidental Database is decoupled // We can test the object } }

检测

  • [x]半自动

我们的 linters 可以在构造函数上找到 SQL 模式并警告我们。

标签

  • 耦合

结论

关注点分离是关键,耦合是我们在设计健壮软件时的主要敌人。

更多信息

学分

<span> Callum HillUnsplash上拍摄的照片</span>


我的信念仍然是,如果你得到正确的数据结构和它们的不变量,大部分代码都会自己编写。


彼得·德斯奇

软件工程名言


Code Smell 143 - 数据块

有些对象总是在一起。我们为什么不把它们分开?


TL;DR:让有凝聚力的原始对象一起移动

问题

  • 内聚力差
  • 重复代码
  • 验证复杂性
  • 可读性
  • 可维护性

解决方案

  1. 提取类
  2. 找小物件

语境

这种气味是原始迷恋的朋友。


如果将两个或多个原始对象粘在一起,业务逻辑和规则在它们之间重复,我们需要找到双射的现有概念。

示例代码

错误的

public class DinnerTable { public DinnerTable(Person guest, DateTime from, DateTime to) { Guest = guest; From = from; To = to; } private Person Guest; private DateTime From; private DateTime To; }

正确的

public class TimeInterval { public TimeInterval(DateTime from, DateTime to) { // We should validate From < To From = from; To = to; } } public DinnerTable(Person guest, DateTime from, DateTime to) { Guest = guest; Interval = new TimeInterval(from, to); } // Even Better... public DinnerTable(Person guest, Interval reservationTime) { Guest = guest; Interval = reservationTime; }

检测

  • [x]半自动

基于内聚模式的检测可用于一些 linter。

标签

  • 凝聚

结论

在正确的位置对行为进行分组并隐藏原始数据。

关系

Code Smell 122 - 原始痴迷

Code Smell 01 - 贫血模型

Code Smell 27 - 关联数组

更多信息

学分

Dynamic Wang 在 Unsplash 上拍摄的照片


该软件的核心是它能够为用户解决与领域相关的问题。所有其他功能,尽管它们可能很重要,但都支持这个基本目的。


埃里克埃文斯

软件工程名言


Code Smell 144 - 可替代对象

我们听说过很多关于 NFT 的信息。现在,我们掌握了 Fungible 的概念。


TL;DR:尊重MAPPER 。使现实世界中的可替代性变得可替代,反之亦然。

问题

解决方案

  1. 识别域中的可替代元素
  2. 将它们建模为可互换的

语境

根据维基百科


可互换性是一种商品或商品的属性,其各个单元本质上是可以互换的,并且每个部分都无法与另一部分区分开来。


在软件中,我们可以用其他对象替换可替代对象。


在将我们的对象与真实对象进行映射时,我们有时会忘记部分模型并构建设计。


示例代码

错误的

public class Person implements Serializable { private final String firstName; private final String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } shoppingQueueSystem.queue(new Person('John', 'Doe'));

正确的

public class Person { } shoppingQueueSystem.queue(new Person()); // The identity is irrelevant for queue simulation

检测

  • [x]手册

这是一种语义气味。


我们需要了解模型以检查它是否正确。

标签

  • 过度设计

结论

让可替代的东西变得可替代,反之亦然。


听起来很简单,但需要设计技巧并避免意外的复杂性。

学分

Andrey MetelevUnsplash上拍摄的照片


人们认为计算机科学是天才的艺术,但实际情况恰恰相反,只是很多人在做事情,就像一堵小石头墙。


唐纳德高德纳


Code Smell 145 - 短路黑客

不要使用布尔计算作为提高可读性的捷径。


TL;DR:不要对副作用函数使用布尔比较。

问题

  • 可读性
  • 副作用

解决方案

  1. 短路转换为 IF

语境

聪明的程序员喜欢编写复杂和晦涩的代码,即使没有强有力的证据证明这种改进也是如此。


过早的优化总是会损害可读性。

示例代码

错误的

userIsValid() && logUserIn(); // this expression is short circuit // Does not value second statement // Unless the first one is true functionDefinedOrNot && functionDefinedOrNot(); // in some languages undefined works as a false // If functionDefinedOrNot is not defined does // not raise an error and neither runs

正确的

if (userIsValid()) { logUserIn(); } if(typeof functionDefinedOrNot == 'function') { functionDefinedOrNot(); } // Checking for a type is another code smell

检测

  • [x]半自动

我们可以检查功能是否不纯并将短路更改为 IF。


一些实际的 linters 警告我们这个问题

标签

  • 过早的优化

结论

不要试图看起来很聪明。


我们不再是 50 年代了。


成为团队开发人员。

关系

Code Smell 140 - 短路评估

Code Smell 06 - 太聪明的程序员

Code Smell 149 - 可选链接

学分

Michael Dziedzic 在 Unsplash 上拍摄的照片


计算机是一台愚蠢的机器,却有能力做难以置信的聪明事情,而计算机程序员是聪明的人,却有能力做难以置信的愚蠢事情。简而言之,他们是绝配。


比尔布赖森


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