6

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

但这让我开始思考:自动生成的代码需要如何具有人类可读性?什么时候应该花费额外的精力来确保生成的代码易于阅读和理解?

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

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

4

22 回答 22

17

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

于 2008-09-15T14:15:53.590 回答
7

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

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

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

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

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

最终,编写代码生成器的开发人员稍后对其进行了重新制作,因此它现在可以生成可读的代码,以防像以前一样出现问题。

这是我刚刚找到的有关当前主题的链接;我实际上是在寻找“实用程序员”一书中的其中一章的链接,以指出我们首先查看代码的原因。

于 2008-09-15T14:35:10.580 回答
3

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

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

于 2008-09-15T14:17:15.087 回答
2

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

于 2008-09-15T14:21:18.650 回答
2

查找主动代码生成被动代码生成。关于被动代码生成,绝对是的,总是。关于主动代码生成,代码达到透明的目标时,它的行为与文档化的 API 完全一样,那么不会。

于 2008-09-15T14:25:16.003 回答
1

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

于 2008-09-15T14:18:46.067 回答
1

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

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

-亚当

于 2008-09-15T14:19:41.913 回答
1

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

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

于 2008-09-15T14:23:57.253 回答
1

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

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

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

于 2008-09-15T14:59:38.290 回答
0

将来有人很可能会想通过并查看您的代码的作用。所以让它有点理解是一件好事。

您可能还希望在每个生成的文件的顶部包含一个注释,说明该文件的生成方式和原因以及它的目的是什么。

于 2008-09-15T14:17:08.423 回答
0

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

于 2008-09-15T14:17:26.520 回答
0

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

于 2008-09-15T14:18:43.350 回答
0

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

于 2008-09-15T14:19:04.880 回答
0

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

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

于 2008-09-15T14:19:08.047 回答
0

逻辑应该总是可读的。如果其他人要阅读代码,试着把自己放在他们的位置上,看看你是否能在不阅读特定代码的情况下完全理解高(和低?)级别的代码。

我不会花太多时间在永远不会被阅读的代码上,但如果不是太多时间,我会浏览生成的代码。如果不是,至少发表评论以弥补可读性的损失。

于 2008-09-15T14:19:28.870 回答
0

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

于 2008-09-15T14:19:45.360 回答
0

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

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

如果你正在做后者,你肯定希望你的代码是人类可读的。

类和接口,无论您认为对开发人员应该多么“禁区”,几乎肯定会属于生成的代码类型 2。调试器会在某个时刻碰到它们——应用代码格式是最少的当编译器命中那些生成的类时,您可以简化调试过程

于 2008-09-15T14:21:51.923 回答
0

就像这里的几乎所有其他人一样,我说让它可读。在您的生成过程中无需花费任何额外费用,您(或您的继任者)在他们挖掘时会很感激。

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

于 2008-09-15T14:24:58.093 回答
0

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

作为一个次要选项,以防你真的那么懒惰,如何在将代码写入磁盘之前通过你选择的美化实用程序管道代码以确保至少某种程度的一致性。尽管如此,我所认识的几乎所有优秀的程序员都对他们的代码进行了迂腐的格式化,这是有充分理由的:没有只写代码。

于 2008-09-15T14:26:11.913 回答
0

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

于 2008-09-15T14:32:19.963 回答
0

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

于 2008-09-15T15:05:49.477 回答
0

我认为答案是:视情况而定。

*这取决于您是否需要将生成的代码配置和存储为人工制品。例如,人们很少保留或配置从 c 编译器输出的目标代码,因为他们知道每次都可以从源代码复制它。我认为这里可能有类似的类比。*这取决于您是否需要根据某些标准对代码进行认证,例如 Misra-C 或 DO178。*这取决于每次编译代码时是否会通过您的工具生成源代码,或者是否将其存储以供以后包含在构建中。

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

于 2008-09-15T15:16:16.940 回答