你的代码能闻到!如何修复

在本文中,我们将重点介绍10种最常见的代码气味,以及如何对它们进行除臭。如果你是一个新的程序员,避免这些,你的代码会明显更好!...

代码气味是一块代码或通用编码模式,看起来它可能表明代码库的整体结构和设计中存在更深层次的问题。

**elly-code-featured

把代码气味看作是任何暗示某段代码应该被重构的迹象。这并不是因为代码有缺陷或者没有功能——通常情况下,有臭味的代码运行得很好——而是臭味的代码通常很难维护和扩展,这可能会导致技术问题(尤其是在大型项目上)。

在本文中,我们将重点介绍10种最常见的代码气味,寻找什么,以及如何去除它们的气味。如果你是一个新的程序员,避免这些,你的代码会明显更好!

1紧耦合

问题

紧密耦合是指两个对象如此依赖于彼此的数据和/或函数,修改一个对象需要修改另一个对象。当两个对象耦合得太紧密时,对代码进行更改可能是一个噩梦,而且每次更改都会引入bug。

例如:

class Worker {
Bike bike = new Bike();
public void commute() {
bike.drive();
}
}

在这种情况下,工人和自行车是紧密耦合的。如果有一天你想开车而不是骑自行车上下班呢?你必须进入工人阶级,用与汽车相关的代码替换所有与自行车相关的代码。很乱,容易出错。

解决方案

您可以通过添加抽象层来放松耦合。在这种情况下,工人阶级不只是想驾驶自行车,还想驾驶汽车,也许是卡车,甚至可能是摩托车。这些都是车辆,不是吗?因此,创建一个Vehicle接口,允许您根据需要**和替换不同的车辆类型:

class Worker {
Vehicle vehicle;
public void changeVehicle(Vehicle v) {
vehicle = v;
}
public void commute() {
vehicle.drive();
}
}
interface Vehicle {
void drive();
}
class Bike implements Vehicle {
public void drive() {
}
}
class Car implements Vehicle {
public void drive() {
}
}

2上帝的目标

问题

一个上帝的对象是包含太多变量和函数的大规模类/模块。它“知道得太多”、“做得太多”,这有两个原因造成问题。首先,其他类/模块过度依赖于此类/模块来获取数据(紧密耦合)。其次,随着所有东西都被塞进同一个地方,程序的整体结构变得浑浊。

解决方案

以上帝为对象,根据它们所存在的问题来分离其数据和函数,然后将这些分组转换为对象。如果你有一个上帝的物体,它可能会更好的组成许多较小的物体。

例如,假设您有一个庞大的用户类:

class User {
public String username;
public String password;
public String address;
public String zipcode;
public int age;
...
public String getUsername() {
return username;
}
public void setUsername(String u) {
username = u;
}
}

您可以将其转换为以下内容的组合:

class User {
Credentials credentials;
Profile profile;
...
}
class Credentials {
public String username;
public String password;
...
public String getUsername() {
return username;
}
public void setUsername(String u) {
username = u;
}
}

下次您需要修改登录过程时,您不必遍历大量的用户类,因为Credentials类更易于管理!

三。长函数

问题

一个长函数就是它听起来的样子:一个长得太长的函数。虽然对于一个函数来说,代码行数“太长”并没有一个具体的数字,但当你看到它时,你就会知道它是什么。这几乎是上帝对象问题的一个更严格的范围版本——一个长函数有太多的责任。

解决方案

长函数应该被分解成许多子函数,每个子函数都被设计用来处理单个任务或问题。理想情况下,原始的长函数将变成子函数调用列表,从而使代码更清晰、更易于阅读。

4参数过多

问题

一个函数(或类构造函数)需要太多参数,这有两个原因。首先,它使代码可读性降低,并且使测试变得更困难。但是第二,更重要的是,它可能表明,该函数的目的过于模糊,并且试图处理太多的责任。

解决方案

虽然“太多”对于参数列表来说是主观的,但是我们建议对任何超过3个参数的函数都要小心。当然,有时一个函数有5个甚至6个参数是有意义的,但前提是有充分的理由。

大多数时候,没有一个,代码最好将该函数分解为两个或多个不同的函数。与“长函数”代码气味不同,这一点不能仅仅通过用子函数替换代码来解决——函数本身需要被划分为包含单独职责的单独函数。

5名称错误的标识符

问题

一个或两个字母的变量名。无法描述的函数名。过度修饰的类名。用它们的类型标记变量名(例如,b\u是一个布尔变量)。最糟糕的是,在一个代码库中混合使用不同的命名方案。所有这些都会导致代码难以阅读、难以理解和维护。

解决方案

为变量、函数和类选择好的名称是一项很难学会的技能。如果您要加入一个现有的项目,请对其进行梳理,看看现有标识符是如何命名的。如果有一个风格指南,记住它并坚持它。对于新项目,考虑形成自己的风格指南并坚持下去。

一般来说,变量名应该简短,但具有描述性。函数名通常应该至少有一个动词,并且应该立即从它的名称就可以看出函数做了什么,但是要避免塞进太多的单词。类名也是如此。

6幻数

问题

你浏览了一些别人写的代码,发现了一些硬编码的数字。也许它们是if语句的一部分,或者是一些似乎没有意义的神秘计算的一部分。你需要修改函数,但是你不能理解数字的含义。划伤头部。

解决方案

在编写代码时,应该不惜一切代价避免这些所谓的“幻数”。硬编码的数字在编写时是有意义的,但是它们很快就会失去所有的意义——特别是当其他人试图维护您的代码时。

一种解决方案是留下解释数字的注释,但更好的选择是将魔术数转换为常量变量(用于计算)或枚举(用于条件语句和开关语句)。通过给神奇数字一个名字,代码一看就变得无限可读,而不太容易发生错误的变化。

7深巢

问题

有两种主要的方法来结束深度嵌套的代码:循环和条件语句。深度嵌套的代码并不总是不好的,但可能会有问题,因为它很难解析(尤其是在变量命名不好的情况下),甚至更难修改。

解决方案

如果您发现自己编写了一个双循环、三重循环,甚至是四倍循环,那么代码可能试图到达超出自身的太远,无法找到数据。相反,提供一种方法,通过函数调用任何对象或模块包含数据来请求数据。

另一方面,深度嵌套的条件语句通常是您试图在单个函数或类中处理过多逻辑的标志。实际上,深嵌套和长函数往往是并行不悖的。如果您的代码有大量的switch语句或嵌套的If-then-else语句,那么您可能需要实现一个状态机或策略模式。

在缺乏经验的游戏程序员中,深度嵌套特别普遍!

8未处理的异常

问题

例外是强大的,但很容易被滥用。懒散的程序员如果不正确使用抛出catch语句,那么调试会变得更困难,如果不是不可能的话。例如,忽略或隐藏捕获的异常。

解决方案

与其忽略或隐藏捕获到的异常,不如至少打印出异常的堆栈跟踪,这样调试器就可以使用了。让你的程序默默地失败,肯定会让你将来头疼!另外,更喜欢捕获特定异常而不是一般异常。在我们的文章中了解更多关于如何正确处理异常的信息。

9重复代码

问题

在程序的多个不相关区域中执行相同的精确逻辑。后来,您意识到需要修改该逻辑,但不记得实现它的所有地方。你最终只改变了8个地方中的5个,导致了错误和不一致的行为。

解决方案

重复代码是转换为函数的主要候选代码。例如,假设您正在开发一个聊天应用程序,并编写以下代码:

String queryUsername = getSomeUsername();
boolean isUserOnline = false;
for (String username : onlineUsers) {
if (username.equals(queryUsername)) {
isUserOnline = true;
}
}
if (isUserOnline) {
...
}

在代码的其他地方,您意识到您需要执行相同的“此用户是否联机?”检查。您可以将循环拉出,而不是复制粘贴循环,而是将其拉出函数:

public boolean isUserOnline(String queryUsername) {
for (String username : onlineUsers) {
if (username.equals(queryUsername)) {
return true;
}
}
return false;
}

现在,在代码的任何地方,都可以使用isUserOnline()检查。如果您需要修改这个逻辑,您可以调整这个方法,它将应用于任何调用它的地方。

10缺乏评论

问题

代码在任何地方都没有任何注释。没有函数的文档块,没有类的使用概述,没有算法的解释等等。人们可能会认为编写良好的代码不需要注释,但事实上,即使是最好的编写代码,也需要比英语更多的精神精力去理解。

解决方案

易于维护的代码库的目标应该是编写得足够好,不需要注释,但仍然有注释的代码。在编写注释时,要针对解释代码片段存在的原因的注释,而不是解释它在做什么。评论有益于心灵和理智。不要忽视他们。

如何编写没有气味的代码

尽管看起来很明显,大多数代码的气味都是由于对良好编程原则和模式的误解或忽视而产生的。例如,对干式原则的坚定遵守消除了大多数代码重复,而掌握单一责任原则几乎不可能创建可怕的上帝对象。

我们还建议阅读关于如何编写更干净的代码的文章,这篇文章着眼于编程更实际的一面。如果你不能一眼就看懂你自己的代码,其他人怎么会呢?清洁代码是无味代码。

在编程方面,你最纠结的是什么?请在下面的评论中与我们分享!

图片来源:SIphotography/Depositphotos

  • 发表于 2021-03-12 10:58
  • 阅读 ( 241 )
  • 分类:编程

你可能感兴趣的文章

如何修复windows拒绝访问错误0x80070005

... 一个干净的引导是一种识别在你的Windows中引起问题的应用程序的方法。它的工作原理是允许你的电脑以最少的程序和驱动程序启动,并帮助你判断哪些程序会导致问题。 ...

  • 发布于 2021-03-11 00:35
  • 阅读 ( 712 )

迄今为止程序员更有趣的10个原因

... 这对你来说意味着你的程序员约会对象会理解你的小怪癖和偏好。就像客户可能希望某个应用程序包含特定的设计一样,有时你可能希望从约会开始就有特定的行为。他们不会认为你的独特...

  • 发布于 2021-03-12 19:23
  • 阅读 ( 214 )

使用任何安卓设备来修复你车上的检查引擎灯

你知道你的车知道更多的信息吗?当仪表板上的基本指示灯和仪表显示里程、燃油和警告信息时,你的车却隐藏了更多的信息。使用Android设备,你可以进入这个网站,不必去看维修工就可以了解更多关于你的汽车的信息。 ...

  • 发布于 2021-03-14 10:16
  • 阅读 ( 157 )

最常见的5个windows错误及其修复方法

...可以解决很多问题,而且只需要一分钟。你可能会发现,你的问题消失后重新启动,特别是如果你没有关闭它一段时间。这是一个好主意,关闭你的电脑至少一周一次,以减少像这样的错误的可能性。 ...

  • 发布于 2021-03-15 00:38
  • 阅读 ( 263 )

如何修复亚马逊prime视频时,它不起作用

...设置(www.amazon.com/gp/video/settings网站). 你也可以在这里管理你的主要视频订阅的其他方面。 ...

  • 发布于 2021-03-17 23:16
  • 阅读 ( 286 )

如何修复windows停止码内存管理bsod

...免除系统错误,就像系统的其他部分一样。当它崩溃时,你的系统也会随之崩溃。 ...

  • 发布于 2021-03-18 06:51
  • 阅读 ( 241 )

windows 10中的关键进程死机?如何修复此停止码

可怕的“死亡蓝屏”,臭名昭著的BSOD,会毁了你的一天。BSOD错误码有500多个,其中最关键的一个是停止码。 ...

  • 发布于 2021-03-18 07:39
  • 阅读 ( 390 )

5个常见googleplay商店问题的简单修复

...对播放商店的更新,然后再次更新。 刷新你的谷歌账户。 在谷歌注册你的设备。 ...

  • 发布于 2021-03-18 07:44
  • 阅读 ( 581 )

如何使用windbg和bluescreenview解决蓝屏错误

...决于错误类型。有时候,粗略的互联网搜索就足以揭示出你的系统出了什么问题。在其他时候,系统调试的特殊软件是您需要的。下面是如何使用WinDbg或NirSoft BlueScreenView修复蓝色屏幕错误的。 ...

  • 发布于 2021-03-22 11:15
  • 阅读 ( 270 )

如何修复windows update错误80072ee2

...Windows10的错误总是令人沮丧,这是肯定的。但他们不必让你的系统长期离线。检查以下六个Windows1080072EE2错误修复程序。 ...

  • 发布于 2021-03-23 12:11
  • 阅读 ( 309 )