写出干净又优美的code的3个小技巧

写出干净又优美的code的3个小技巧

你可能听说过“乱码”,并且想知道乱码意味着什么(当你的代码无论怎样工作时),或者遇到过一些编码最佳实践术语,例如SOLID设计原则、DRY(避免重复代码)或KISS(保持简约)原则。

编码最佳实践中有太多行业术语和规则,它令人困惑,重复乏味(来自KISS和 DRY原则的讽刺),我怀疑是否会在实践中有效,因为它们毕竟是理论上的。

本文旨在提供一个速成课程,总结良好的编码标准、编码最佳实践、不同的代码异味和设计模式,并以3个编写干净代码的实用技巧结束。如果你想了解更多关于数据科学的相关内容,可以阅读以下这些文章:
职场转型与进阶:多年非Data相关工作经验,如何转行数据科学家?
初级与高级数据科学家有什么区别?
如何明确和解决模糊的数据科学问题?
构建数据科学管道的 4 个步骤

目录

  1. 编码标准
  2. 最佳编码实践
  3. 代码异味
  4. 设计模式
  5. 技巧 1:规划组件
  6. 技巧 2:不断抽象代码
  7. 技巧 3:利用开源工具

编码标准

编码标准定义了编码规范或设计规范,例如英语如何遵循语法规则,而遵循编码规范的代码提高了代码的可读性和可理解性。

不同编程语言的编码标准通常遵循相同的规则,但可能略有不同,因为不同的语言具有不同的语法。Python有PEP 8标准,Java有Oracle创建的代码规范。

本文与语言无关,编码标准通常定义的规则为:

  • 文件夹和文件结构(用于Java)
  • 缩进和间距
  • 包、模块、类、变量名等的命名规则。
  • 执行导入、编写注释和语句的正确方法

在上面的每个类别中,都可以遵循很多规则——PEP 8文档中甚至还有一个关于“pet peeves”的部分!由于要遵循这么多规则,很难记住或很容易错过某些违规行为,就像英语中有拼写错误一样。

有一些工具可以标记出不遵循编码标准的代码,例如IDE(集成开发环境),它为不遵循编码标准的代码加下划线,或者重新格式化和重写代码的包,称为code linting。例如,有助于linting的一些Python包有pylint、black和flake8。

编码最佳实践

编码最佳实践定义了构建代码的理论和准则,以增强代码的模块化和可维护性。

如本文开头所述,在编码最佳实践的大框架下使用了很多行业术语。在下图中总结并绘制了常见术语之间的联系。这是一个总结,而不是举例详细说明。

图 1:规范和指南摘要 — 作者图片

遵循SOLID设计原则:

  • 单一职责原则:一个类应该只包含一份职责
  • 开放封闭原则:一个类应该对扩展是开放的,对修改是封闭的。即可扩展,不可修改。
  • Liskov替换原则:程序中的对象可以用它们的子类型的实例替换而不改变程序的正确性
  • 接口隔离原则:客户端不应被强迫实现一些它不会使用的接口
  • 依赖倒置原则:高级模块应依赖于高级泛化,而不是低级细节

其他设计原则和指南包括:

  • 组合对象原则:类应该通过聚合而不是继承来实现代码重用
  • Demeter定律/最少知识原则:类应该与尽可能少的其他类交互
  • 抽象:通过仅显示相关信息来简化
  • 封装:将属性和行为绑定到对象中,并根据需要公开特征
  • 分解:将实体分解成可以单独实现的部分
  • 泛化:分解出可以在其他地方重用的类的共同特征
  • 耦合和内聚:低耦合的模块依赖较少且更容易重用,而高内聚描述了一个具有明确目的且不需要更复杂的模块
  • 继承:子类从父类继承或通过接口实现的属性或行为
  • 信息隐藏:模块应该只能访问它需要执行的信息
  • 关注点分离:不同的关注点应该在不同的模块中
  • 避免重复:减少代码的重复
  • 保持简洁:简洁应该是设计目标
  • 概念完整性:创建一致的软件并决定如何设计和实施系统

主要的收获是有很多原则,但有些原则是相反的!例如,封装和分解,这就引出了一个问题,你应该在什么时候使用每个原则?

在实践中,我们会在适用的情况下行使这些原则,我们甚至可能会根据具体情况违背某些“大多数利益”原则。这些原则了解一下就足够了,不应将其作为完成清单来实施。

代码异味

代码异味是不良代码的症状,这可能表明存在更深层次的问题。

与编码最佳实践类似,知道它们的存在就足够了,而不是强制或可能避免代码中的所有代码异味。代码异味也很难避免,因为它们可能是基于开发人员、编程语言和问题类型的主观因素。

更常见的代码异味是:

  1. 注释:有注释固然好,但如果过度使用注释(主观的)来弥补代码的不清晰,那就是个问题
  2. 过大的类:如果一个类非常大(主观),考虑使用分解
  3. 数据类:如果类太小(主观);与过大的类对立
  4. 数据泥团:如果一组代码经常同时出现,请考虑使用封装
  5. 重复代码:如果在代码库的多个部分中发现相同的代码,且变动很小,请考虑使用泛化
  6. 过长函数:如果函数过长(主观),这表明关注点分离不佳,请考虑使用分解
  7. 过长参数列表:如果函数的参数列表很长(主观),请考虑传递封装常用参数的对象
  8. 霰弹式修改:如果一个地方的变化导致多个其他部分的变化,这表明紧密耦合

以上项目是常见代码异味的非详尽列表,完整的代码异味列表可以点击此处。从上面的列表中可以看出,代码异味可能非常主观,并且与编码最佳实践密切相关——如果你努力练习和实施编码最佳实践,代码异味也可以最小化。

设计模式

设计模式为常见的软件工程问题提供解决方案,并且与语言和代码无关。

设计模式分为三种类型——创建型、结构型和行为型设计模式。

  • 创建型设计模式定义了为对象实例化的设计方法,例如使用继承或封装实例化对象的不同方法等。
  • 结构设计模式定义了创建类和关系的设计方法,重点是保持它们的灵活性和效率。
  • 行为设计模式定义了设计相关类的行为的方法,重点是类和对象之间如何相互通信。

虽然设计模式更适用于面向对象的编程,但其设计概念与代码无关。了解不同的设计模式使你能够选择更适用于问题的设计模式。设计模式的完整列表可以点击这里。

技巧1:规划组件

“如果你没有计划,你就会失败” ——本杰明·富兰克林

始终仔细检查项目需求并规划组件,以防止将来出现重大的代码重组。

在大多数情况下编写代码时,你确实对代码库的结构有所了解。例如,数据科学工作流被结构化为数据获取、数据处理、特征工程、建模和评估组件,并为每个组件创建单独的文件夹或文件,作为关注点分离最佳实践的一部分。

这些组件可以源自项目的性质(在本例中为数据科学工作流程),也可以是特定于项目的组件。如果项目需要添加额外的组件,例如数据分析,请尽早规划将其包括在内。

最后,除了与代码相关的组件外,规划与数据相关的组件也很重要。确定要加载和保存的数据量和内容,并设计数据的存储方式!

技巧2:不断抽象代码

“设计是一个迭代的过程。一个想法往往建立在另一个想法之上” ——马克·帕克

在上一节后,当你完成所有组件时,代码可以正常工作并且没有任何中断 – 但它会在未来中断吗?可能会有更改,新的需求、数据、功能或实施方法。

假设数据路径发生了更改,并且你最终更改了代码的多个部分以从新路径中读取——这意味着霰弹式修改的代码异味。你将数据路径抽象到配置文件中,问题就解决了。

第二天,数据格式发生了变化,你最终改变了代码的多个部分以改变数据的读取方式——这也意味着霰弹式修改的代码异味。你将代码抽象到加载数据的新函数,问题也解决了。

这就是问题的开始——你是否应该事先进行抽象?你第一次没有正确规划你的组件吗?然而,如果过度抽象代码,这可能会导致不必要的复杂性,因为你过度设计代码(这也是另一种代码异味)。这是在理论和实践中编码的冲突。

一般的经验法则是执行关注点分离,而不是硬编码变量。如果必须在项目过程中将组件抽象出来,那也没关系 – 变化确实会发生,编码是迭代循环的。

技巧3:使用开源工具

不要浪费时间做无用功

由于现在每个组件都是分离的,因此很容易想从头开始实现每个组件。手动实现组件也使开发人员可以更好地控制流程,因为每个部分都可以根据需要进行调整。

但是,你编写的代码越多,代码库越复杂,其他开发人员就越难理解你的代码库。如果其他开发人员不了解你的代码库,将来就很难维护。利用其他开发人员广泛使用和熟知的开源工具会更容易。

例如,如果你正在安排工作,请使用 Apache Airflow。如果你正在进行实验,请使用 MLFlow 跟踪。它们通常由自己的开发人员更好地开发和维护,利用开源工具并将其集成到项目中,这样可以减少顾虑。

结论

从队友及自己的代码库中重构和重组多个代码库后,我发现这些技巧很有用,可以节省很多时间和精力。编码实际上是一个迭代循环,即使遵循编码最佳实践,仍发现自己在进行调整和更改。希望这篇文章对编码标准、最佳实践、代码异味和设计模式有所启发,并希望你在以后的项目中遵循这些实用技巧!

总而言之,这些是本文分享的 3 个技巧:

  • 规划组件
  • 不断抽象代码
  • 使用开源工具

感谢你的阅读!如果你喜欢这篇文章,请随意分享。你还可以订阅我们的YouTube频道,观看大量大数据行业相关公开课:https://www.youtube.com/channel/UCa8NLpvi70mHVsW4J_x9OeQ;在LinkedIn上关注我们,扩展你的人际网络!https://www.linkedin.com/company/dataapplab/

原文作者:Kay Jan Wong
翻译作者:过儿
美工编辑:过儿
校对审稿:Miya
原文链接:https://towardsdatascience.com/3-tips-for-writing-clean-codes-beyond-coding-best-practices-c53b04120c3