使用实例告诉你如何重构带有坏味道的代码

摘要:假如出现了代码坏味道,说明你的代码写得不够好,需要重构才能让它们变成干净的代码。在这篇文章中,我将通过 GitHub 上的真实项目来解释代码坏味道,并向你展现如何重构这些带有坏味道的代码。重复代码和重复逻辑开发人员通常很懒惰,在某种程度上,这不算一件坏事。然而,由于懒惰而走上了复制黏贴代码的不归路那

假如出现了代码坏味道,说明你的代码写得不够好,需要重构才能让它们变成干净的代码。在这篇文章中,我将通过 GitHub 上的真实项目来解释代码坏味道,并向你展现如何重构这些带有坏味道的代码。

重复代码和重复逻辑

开发人员通常很懒惰,在某种程度上,这不算一件坏事。然而,由于懒惰而走上了复制黏贴代码的不归路那就不对了。这样可能会导致最常见的代码坏味道,即逻辑重复,如下所示。

为了摆脱这种代码坏味道,我们需要将红色部分提取到一个单独的方法中,这样即可以在其余地方重使用它们。

长方法和臃肿的类

我们都会犯这样的一个错误:在现有方法中增加 if() 或者 for() 语句来验证使用户输入或者检查使用户能否已登录。我们其实不应该这样做。假如肯定要做这些验证,应该创立自己的方法。方法长度应该在 4 到 20 行之间,假如超过 20 行,可以将其中的几行提取到另一个方法中。同样的规则也适使用于类,根据单一责任准则,方法或者类越小越好。

相同或者不同类中的重复方法

另一个代码坏味道是多个方法提供了相同的功能,如下图所示。

分散式变更(Divergent Change)

假如你理解 SOLID 准则,特别是单一职责准则,那么你就应该知道,修改一个类的理由应该是单一的。也就是说,User 类不应具备与产品或者文件转换相关的功能。你可以通过将不相关的方法提取到 Product 类或者 FileSystem 类来清理这个代码坏味道。

散弹式变更(Shotgun Surgery)

这与发散变更完全相反。这种代码坏味道会让你由于一个需求而去修改多个类。例如,你想要创立一个新的使用户规则(如“Supper-Admin”),而后你发现,为了添加这个规则还需要修改 Profile、Products 和 Employees 类中的某些方法。在这种情况下,可以考虑将这些方法放在一个单独的类中。

依恋情结(Feature Envy)

有时候,你会在类中找到一个大量用另一个类的方法。在这种情况下,你可以考虑将这个方法移动到它用的那个类中。如下图所示。将 getFullAddress() 从 User 类移动到 ContactInfo 类中岂不是更好?由于它调使用了 ContactInfo 类的很多方法。

数据泥团(Data Clumps)

有时候,你会发现很多函数具备相同的参数列表,这样会导致数泥团代码坏味道。看看下面的例子,你会发现,几乎所有类型的预订都需要护照信息。

在这种情况下,将护照信息移到 PassportInfo 类中,而后将 PassportInfo 对象传给预订方法,这样会更好。这是一个很好的重使用代码的例子。请记住,参数列表太长可能更容易导致 bug 和代码冲突,而且难以进行单元测试。

痴迷基本类型(Primitive Obsession)

当你在应使用程序的所有地方都用基本数据类型时,就会出现这种代码坏味道。例如,用整数表示电话号码,用字符串表示货币符号。假如你是这么做的,那么请先看一下下面这个类。

代码中的地址被定义为数组,这样会导致两个问题,例如,每次我们需要用地址时都要对其进行硬编码。那么,为什么不创立一个 Address 类呢?

现在,每次我们需要增加或者编辑地址时,只要要修改 Address 类。此外,假如我们需要增加一个新的“联络我们”方法,就添加一个新的 ContactUs 类。这样,每个类都有自己的单一职责。

switch 语句

或者许你很想知道为什么用 switch 语句其实是件很糟糕的事情。虽说用 switch 语句并不肯定总是不好的,但在下面的示例中,你可以看到,switch 语句的代码块不仅很大而且是不可提取的。当代码块变得越来越大时,你将无法将其拆分成更小的方法。

假如你的 switch 语句代码块不是很大,那么你可以继续用它们。例如,工厂模式就用了 switch 语句。

并行继承

有时候我会想,并行继承是不是一种不好的做法。先让我们来解释一下并行继承的概念,而后再探讨它是不是代码坏味道。

从上图中可以看出,每当我们创立一个新的部门类时,我们还需要创立一个权限类,这将导致之前提到的散弹式变更代码坏味道。

懒惰类

懒惰类是指只做很少事情的类。还记得这些下面这些代码吗?

我们将地址移到一个单独的类中,但我们没有对热线也这么做,由于它可能只有 3 行代码。所以,一旦你发现了这些懒惰类,应该将它们移除。

临时字段

当一个类实例的某些变量只是偶尔使用到,就出出现临时字段代码坏味道。请看下面的例子,你会注意到 $name 和 $contactDetails 只在 notify() 方法中使用到。

那么为什么不将它们作为方法参数进行传递呢。

消息链

当一个类用了另一个类,而那个类又用了另外一个类,并以此类推,那么就会出现消息链代码坏味道。在下图中,你可以看到 Employee->EmployeeConfig->Config。

你可以通过缩短链(变成 Employee->Config)让代码变得更整洁。

不恰当的亲密关系

有时候,一个类的某个方法需要过多地理解另一个类的内部状态或者数据。正如你在下图中所看到的,notify() 方法位于 User Class 中,但它却用了 UserContactDetails 类的很多内部方法。

在这种情况下,最好可以将这些逻辑从 User 类移动到 UserContactDetails 类中,并新添加 getWelcomeMessage($userName) 方法。

中间人

有时候,你会发现一个类的很多方法什么事都不做,只是将调使用委托给另一个类。在这种情况下,这个类被认为是中间人,大多数时候可以避免用它。

注意:在 Facade 设计模式中,中间人在某些情况下可能会有所帮助。

接口不同但目的相同的类

通常,由于团队之间缺乏沟通,创立了两个不同的类,但它们的作使用却是一样的,这意味着出现了重复代码。

不完整的库

第三方库并不总能为你提供应使用程序中所需的所有功能。在下面的示例中,解决文档的库可以通过 ID 获取一个文档或者一次获取所有的文档。

假如你需要获取特定使用户的所有文档该怎样办?在这种情况下,你需要扩展 Document 类的功能,而不直接修改原始类。这个时候可以用装饰模式,如下图所示。

现在,你可以用 DocumentsDecorator 类而不是 Documents 类。

注释

你可能会感到惊讶,但错误地用注释也是一种代码坏味道。下面是我的少量建议:

删除不必要的注释。

假如代码很容易了解,请不要增加额外的注释。

不要留下被注释的旧代码。

删除使用于调试的注释,如 var_dump、echo 等。

夸夸其谈未来性(Speculative Generality)

这个代码坏味道与过早进行优化有关,很多开发人员都没有注意到这一点。在规划期间需要考虑的少量注意事项:

不要过度计划你的代码。

不要试图涵盖只有 1%可能性会在未来发生的情况。

为了让算法更简单,可以牺牲少量速度,特别是当你不需要应使用程序立即给出结果的时候。

当应使用程序速度很慢,即便只有 100 个使用户,也需要进行优化。

英文原文:https://codeburst.io/write-clean-code-and-get-rid-of-code-smells-aea271f30318

假如大家喜欢这篇文章的话,希望大家能够收藏,转发 谢谢!更多相关资讯可以关注西安华美校区,免费取得java零基础教程!额外附送excel教程!

  • 全部评论(0)
最新发布的资讯信息
【系统环境|】2FA验证器 验证码如何登录(2024-04-01 20:18)
【系统环境|】怎么做才能建设好外贸网站?(2023-12-20 10:05)
【系统环境|数据库】 潮玩宇宙游戏道具收集方法(2023-12-12 16:13)
【系统环境|】遥遥领先!青否数字人直播系统5.0发布,支持真人接管实时驱动!(2023-10-12 17:31)
【系统环境|服务器应用】克隆自己的数字人形象需要几步?(2023-09-20 17:13)
【系统环境|】Tiktok登录教程(2023-02-13 14:17)
【系统环境|】ZORRO佐罗软件安装教程及一键新机使用方法详细简介(2023-02-10 21:56)
【系统环境|】阿里云 centos 云盘扩容命令(2023-01-10 16:35)
【系统环境|】补单系统搭建补单源码搭建(2022-05-18 11:35)
【系统环境|服务器应用】高端显卡再度登上热搜,竟然是因为“断崖式”的降价(2022-04-12 19:47)
手机二维码手机访问领取大礼包
返回顶部