我正在开发一个工具,该工具将为接口和实现该接口的几个类生成源代码。我的输出并不是特别复杂,因此使输出符合我们正常的代码格式标准并不困难。

但这让我思考:自动生成的代码需要具有怎样的人类可读性?什么时候应该付出额外的努力来确保生成的代码易于人类阅读和理解?

就我而言,我生成的类本质上只是与构建的另一部分相关的一些数据的容器,以及获取数据的方法。没有人需要查看类本身的代码,他们只需要调用类提供的各种 getter 即可。因此,代码是否“干净”、格式良好且易于人类阅读可能并不是太重要。

但是,如果您生成的代码中包含大量简单逻辑,会发生什么情况?

有帮助吗?

解决方案

我认为生成的代码可读并遵循正常的编码风格同样重要。在某些时候,有人要么需要调试代码,要么需要了解“幕后”发生的情况。

其他提示

是的,一点没错!;我什至可以给你讲一个故事来解释为什么人类可以轻松阅读自动生成的代码很重要......

我曾经有机会参与一个新项目。现在,当您开始编写代码时,您需要做的第一件事就是创建某种与数据库之间的连接和数据表示。但是,我们不只是手工编写这些代码,而是有人开发了自己的代码生成器来从数据库模式自动构建基类。这真的很简洁,编写所有这些代码的乏味工作现在已经脱离了我们的控制......唯一的问题是,生成的代码对于 普通的 人类。

当然我们没有这样做,因为嘿,它只是为我们节省了很多工作。但过了一段时间,事情开始出错,从用户输入中错误地读取了数据(或者我们是这么认为的),当我们在其中时,数据库内部发生了损坏。 仅有的 阅读。奇怪的..因为读取不会改变任何数据(同样,我们认为)......

像任何优秀的开发人员一样,我们开始质疑自己的代码,但经过几天的搜索......即使重写代码,我们也找不到任何东西......然后我们意识到,自动生成的代码被破坏了!

因此,现在等待着我们的是一个更大的任务,检查自动生成的代码,而理智的人在合理的时间内无法理解这些代码......我说的是非缩进的、非常糟糕的风格代码,带有难以发音的变量和函数名称......事实证明,我们自己重写代码甚至会更快,而不是试图弄清楚代码实际上是如何工作的。

最终,编写代码生成器的开发人员后来重新编写了它,所以现在它生成了 可读的 代码,以防像以前一样出现问题。

这是 我刚刚找到的链接 关于当前的话题;我实际上是在寻找指向其中一章的链接 《务实的程序员》一书 指出为什么我们首先查看代码。

我认为这取决于生成的代码将如何使用。如果代码不适合人类阅读,即每当发生变化时它就会重新生成,我认为它不必可读。但是,如果您使用代码生成作为“正常”编程的中间步骤,则生成的代码应该具有与源代码的其余部分相同的可读性。

事实上,使生成的代码“不可读”可能是一个优势,因为它会阻止人们“破解”生成的代码,而是在代码生成器中实现他们的更改 - 每当您需要重新生成代码时,这都非常有用无论出于何种原因,都不要丢失同事所做的更改,因为他认为生成的代码已“完成”。

是的,它确实。首先,您可能需要对其进行调试——您自己可以轻松做到这一点。其次,它应该遵守您在商店中使用的任何编码约定,因为有一天可能需要手动更改代码,从而成为人类代码。当您的代码生成工具不能涵盖您需要的某一特定内容并且认为不值得仅仅为此目的修改该工具时,通常会出现这种情况。

抬头 主动代码生成被动代码生成. 。关于被动代码生成, 绝对是的,总是。 关于主动代码生成, 什么时候 代码实现了透明的目标,这与文档化的 API 完全一样,那就不行。

我想说的是,代码必须是人类可读的,除非你的代码生成工具有一个优秀的调试器,否则你(或不幸的同事)可能会深入代码试图跟踪那个难以捉摸的错误在系统中。我自己对“UML 代码”的探索给我留下了苦涩的味道,因为我无法掌握所谓的“花哨”调试过程。

生成代码的全部目的是做一些“复杂”的事情,这些事情在某种高级语言中更容易定义。由于它是生成的,因此生成的代码的实际维护应该在生成代码的子例程内,而不是生成的代码内。

因此,人类可读性应该具有较低的优先级;诸如运行速度或功能之类的东西要重要得多。当您查看 bison 和 flex 等工具时尤其如此,它们使用生成的代码预先生成快速查找表来进行模式匹配,这对于手动维护来说简直是疯狂的。

如果您必须调试自己生成的代码,您就会自杀。 不要开始认为你不会。 请记住,当您信任代码生成代码时,您就已经向系统引入了两个错误 - 您已经将自己插入了两次。

绝对没有理由不让它被人类解析,那么你到底为什么要这样做呢?

-亚当

没有提到的问题的另一个方面是生成的代码也应该是“版本控制友好的”(只要可行)。

我发现多次检查生成代码与源代码中的差异很有用。

这样,您甚至可以偶尔在生成代码的工具中发现错误。

将来很可能有人想要浏览并查看您的代码的作用。所以让它变得容易理解是一件好事。

您可能还希望在每个生成的文件的顶部添加一条注释,说明该文件的生成方式和原因以及其用途。

一般来说,如果您生成的代码需要稍后进行人工修改,则它需要尽可能具有人类可读性。然而,即使它将生成并且再也不会触及的代码,它仍然需要足够的可读性,以便您(作为编写代码生成器的开发人员)可以调试生成器 - 如果您的生成器吐出错误的代码,则可能很难追踪是否难以理解。

我认为花额外的时间使其易于阅读以使其更易于调试是值得的。

生成的代码应该是可读的(格式等通常可以由一个不错的 IDE 处理)。在代码生命周期的某个阶段,有人会查看它,并且他们会想要理解它。

我认为对于工作非常简单的数据容器或对象来说,人类可读性并不是很重要。

然而,一旦开发人员可能需要阅读代码来了解事情是如何发生的,它就需要具有可读性。如果逻辑有bug怎么办?如果没有人能够阅读和理解代码,怎么会有人发现它呢?我什至会为更复杂的逻辑部分生成注释,以表达意图,因此更容易确定是否确实存在错误。

逻辑应该始终是可读的。如果其他人要阅读代码,请尝试将自己置于他们的位置,看看您是否能够在不阅读特定代码的情况下完全理解高(和低?)级别的代码。

我不会花太多时间处理永远不会被阅读的代码,但如果不是太多时间,我会仔细检查生成的代码。如果没有,至少发表评论以弥补可读性的损失。

如果此代码可能会被调试,那么您应该认真考虑以人类可读的格式生成它。

生成的代码有不同类型,但最简单的类型是:

  1. 生成的代码不适合开发人员看到。例如,定义布局的 xml-ish 代码(想想 .frm 文件,或者 SSIS 生成的可怕文件)
  2. 生成的代码旨在成为稍后由开发人员自定义的类的基础,例如,生成代码是为了减少打字的乏味

如果你选择后者,你 确实 希望您的代码易于人类阅读。

类和接口,无论您认为它们对开发人员来说应该是多么“禁区”,几乎肯定会属于生成代码类型 2。它们将在某一点被调试器击中——应用代码格式化是当编译器击中这些生成的类时您可以简化调试过程的至少一种方式

和这里的几乎其他人一样,我说要让它可读。在您的生成过程中不需要花费任何额外费用,并且您(或您的继任者)在挖掘时会感激不尽。

对于现实世界的示例 - 查看 Visual Studio 生成的任何内容。格式良好,有评论和一切。

生成的代码就是代码,没有理由任何代码不可读且格式良好。这很便宜,尤其是在生成的代码中:您不需要自己应用格式,生成器每次都会为您完成!:)

作为辅助选项,如果您真的那么懒,可以在将代码写入磁盘之前通过您选择的美化器实用程序管道传输代码,以确保至少某种程度的一致性。尽管如此,我认识的几乎所有优秀程序员都相当迂腐地格式化他们的代码,这是有充分理由的:没有只写代码。

绝对是的,因为上面已经说过了很多充分的理由。还有一个问题是,如果您的代码需要由评估者检查(出于安全性和可靠性问题),那么如果代码是人类可重新编写的,那就更好了。如果没有,评估员将拒绝评估,您的项目将被当局驳回。唯一的解决方案是评估...代码生成器(这通常要困难得多;))

这取决于代码是只能由编译器读取还是也可以由人类读取。此外,代码是否应该超快或可读性是否重要也很重要。如有疑问,请付出额外的努力来生成可读的代码。

我想答案是:这取决于。

*这取决于您是否需要配置生成的代码并将其存储为工件。例如,人们很少保留或配置 C 编译器输出的目标代码,因为他们知道每次都可以从源代码重现它。我想这里可能也有类似的类比。*这取决于您是否需要根据某些标准验证代码,例如Misra-C 或 DO178。*这取决于每次编译代码时是否通过您的工具生成源代码,或者是否将其存储起来以便稍后包含在构建中。

就我个人而言,如果您想做的只是构建代码,将其编译成可执行文件,然后扔掉中间代码,那么我看不出有任何让它变得太漂亮的意义。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top