我使用MyGeneration和nHibernate来创建基本的POCO对象和XML映射文件。我听说有些人说他们认为代码生成器并不是一个好主意。目前最好的想法是什么?只是当它生成数千行不可理解的代码时,代码生成是不好的?
答案 0 :(得分:23)
代码生成器生成的代码不应(作为概括)用于随后通过人为干预进行编辑的情况。一些系统,例如Visual C ++的各种化身上的向导生成的代码,程序员随后希望手动编辑。这并不受欢迎,因为它要求开发人员挑选生成的代码,理解它并进行修改。这也意味着生成过程是一次性的。
生成的代码应该与系统中的其他代码存在于单独的文件中,并且只能从生成器生成。生成的代码应该清楚标记,以表明人们不应该修改它。我曾经有过这样或那样的代码生成系统,并且如此生成的 All 代码在序言中有类似的内容:
-- =============================================================
-- === Foobar Module ===========================================
-- =============================================================
--
-- === THIS IS GENERATED CODE. DO NOT EDIT. ===
--
-- =============================================================
Code Generation in Action是一本关于这个主题的好书。
答案 1 :(得分:15)
代码生成器很棒,代码很糟糕。
此页面上的大多数其他回复都是“否,因为生成的代码通常不是很好。”
这是一个糟糕的答案,因为:
1)生成器就像其他任何工具一样 - 如果你滥用它们,就不要责怪这个工具。
2)开发人员倾向于为自己编写优秀代码的能力感到自豪,但是你不会将代码生成器用于一次性项目。
我们使用代码生成系统在所有Java项目中保持持久性,并且在生产中有数千个生成的类。
作为经理,我喜欢他们,因为:
1)可靠性:该代码中没有明显的剩余错误。多年来,它经过了如此详尽的测试和改进,而不是在调试时我从不担心持久层。
2)标准化:在这方面,每个开发人员的代码都是相同的,所以当一个同事从同事那里学习新项目时,他们学到的东西要少得多。
3)进化:如果我们找到更好的方法,我们可以更新模板并快速一致地更新1000个类。
革命:如果我们将来切换到不同的持久性系统,那么每个持久化类都具有完全相同的API这一事实使我的工作变得更加容易。5)生产力:只需点击几下即可从元数据构建持久对象系统 - 这可以节省数千个无聊的开发人员时间。
代码生成就像使用编译器一样 - 在个别情况下你可以编写更好的优化汇编语言,但是对于大量的项目,你宁愿让编译器为你做这件事吗?
我们使用一个简单的技巧来确保始终可以重新生成类而不会丢失自定义:每个生成的类都是抽象的。然后开发人员使用具体类扩展它,添加自定义业务逻辑并覆盖他想要与标准不同的任何基类方法。如果元数据发生变化,他可以随时重新生成抽象类,如果新模型打破了他的具体类,编译器就会让他知道。
答案 2 :(得分:11)
我使用代码生成器时遇到的最大问题是维护期间。如果您修改生成的代码,然后对架构或模板进行更改并尝试重新生成,则可能会出现问题。
一个问题是,如果该工具不允许您保护您对修改后的代码所做的更改,那么您的更改将被覆盖。
我见过的另一个问题,特别是RSA中用于Web服务的代码生成器,如果您过多地更改生成的代码,生成器会抱怨不匹配并拒绝重新生成代码。对于像更改变量类型这样简单的事情,可能会发生这种情况。然后,您不得不将代码生成到另一个项目并将结果合并回原始代码。
答案 3 :(得分:8)
代码生成器可以提高工作效率,但有几点需要注意:
让您以您想要的方式工作。
如果您必须弯曲未生成的代码以适应生成的代码,那么您应该选择不同的方法。
作为常规版本的一部分运行。
应将输出生成到中间目录,而不是检入源代码管理。但是,输入必须签入源控件。
无安装
理想情况下,您也可以将工具检入源控件。让人们在准备新的构建机器时安装东西是坏消息。例如,如果您进行分支,则希望能够使用代码对工具进行版本化。
如果必须,请创建一个脚本,该脚本将使用包含源树副本的干净机器,并根据需要配置计算机。请完全自动化。
无编辑输出
您不必编辑输出。如果输出不够实用,则该工具不适合您。
此外,输出应清楚地表明它是一个生成的文件&不应该编辑。
可读输出
输出应写入&格式化得很好您希望能够打开输出和输出读它没有太多麻烦。
<强> #line
强>
许多语言都支持类似#line
指令的东西,它允许您将输出的内容映射回输入,例如在生成编译器错误消息或步进调试器时。这可能很有用,但除非做得非常好,否则它也会很烦人,所以这不是必需的。
答案 4 :(得分:6)
我的立场是代码生成器并不坏,但很多人都使用它们。
如果你使用代码生成器节省时间来编写好的代码,那么很好,但往往没有优化,或者增加了很多开销,在这些情况下我觉得它很糟糕。
答案 5 :(得分:2)
如果您希望将行为混合到您的课程中,代码生成可能会让您感到悲伤。同样富有成效的替代方案可能是属性/注释和运行时反射。
答案 6 :(得分:2)
编译器是代码生成器,因此它们本身并不坏,除非您只想在原始机器代码中编程。
但我相信代码生成器应始终完全封装生成的代码。即您应该从不手动修改生成的代码,任何更改都应该通过修改生成器的输入并重新生成代码来完成。
答案 7 :(得分:1)
我们当前的项目大量使用代码生成器。这意味着我已经看到了第一次生成代码的“显而易见”的好处 - 没有编码器错误,没有拼写错误,更好地遵守标准编码风格 - 以及在维护模式下几个月之后,意外的缺点。实际上,我们的代码生成器最初确实提高了我们的代码库质量。我们确保它完全自动化并与我们的自动构建集成。但是,我会说:
(1)代码生成器可以是拐杖。我们现在在系统中有几个庞大而丑陋的难以维护的代码,因为在过去的某个时刻,我们的代码生成XML文件中添加了20个新类比进行适当的分析和类更容易重构。
(2)规则的例外情况会杀死你。我们使用代码生成器创建数百个Screen和Business Object类。最初,我们对类中可能出现的方法强制执行标准,但与所有标准一样,我们开始制作例外。现在,我们的代码生成XML文件是一个巨大的怪物,充满了插入到选定类中的Java代码的特殊情况片段。解析或理解几乎是不可能的。
(3)由于使用数据库中的值生成了大量代码,因此开发人员很难在各自的工作站上维护一致的代码库(因为可以有多个版本的数据库)。通过软件进行调试和跟踪要困难得多,并且由于类之间的额外抽象和隐式关系,团队的新手需要更长的时间才能找出代码的“流程”。 IDE无法获取通过代码生成的类进行通信的两个类之间的关系。
现在可能已经够了。我认为代码生成器是开发人员个人工具包的一部分;一组编写样板代码的脚本使得启动项目变得更加容易。但代码生成器不会使维护问题消失。
答案 8 :(得分:1)
许多人在使用代码生成时犯的错误是编辑生成的代码。如果你记住,如果你觉得你需要编辑代码,你实际上需要编辑代码生成工具,这对生产力是一个福音。如果你经常与生成的代码作斗争,最终会导致生产力下降。
我发现的最好的代码生成器是允许您编辑生成代码的模板的代码生成器。我真的很喜欢Codesmith,因为它是基于模板的,模板很容易编辑。当您发现生成的代码存在缺陷时,您只需编辑模板并重新生成代码,之后您将永远保持良好状态。
我发现的另一件事是许多代码生成器不易与源代码控制系统一起使用。我们已经解决这个得到的方式是在模板检查的而不是代码和唯一的事情,我们检查到生成的源代码控制是生成代码的编译版本(DLL文件,大多)。这可以为您节省很多麻烦,因为您只需要检入几个DLL而不是数百个生成的文件。
答案 9 :(得分:1)
我之前写过一些代码生成器 - 说实话,他们不止一次地保存了我的屁股!
一旦你有一个明确定义的对象 - 集合 - 用户控件设计,你可以使用代码生成器为你构建基础知识,让你作为开发人员的时间更有效地用于构建复杂的东西,毕竟,谁真的想写300多个公共财产声明和变量实例?我宁愿陷入业务逻辑而不是所有无意识的重复性任务。
答案 10 :(得分:1)
如果它是Fran Tarkenton试图卖给你的大型机cobol代码生成器那么绝对是的!
答案 11 :(得分:0)
代码生成器很棒,假设它是一个很好的代码生成器。特别是工作c ++ / java非常详细。
答案 12 :(得分:0)
在最近的一个项目中,我们构建了自己的代码生成器。我们生成了所有数据库内容,以及视图和视图控制器类的所有基本代码。尽管生成器需要花费几个月的时间来构建(主要是因为这是我们第一次这样做,而且我们有一些错误的启动),但是我们第一次运行它并为整个应用程序生成了基本框架。大约十分钟。 这完全是用Java编写的,但Ruby是一种优秀的代码编写语言,特别适用于小型的一次性类型项目。 最好的是代码和项目组织的一致性。另外,你必须提前考虑基本框架,这总是好的。
答案 13 :(得分:0)
代码生成器的最佳应用是当整个项目是模型时,所有项目的源代码都是从该模型生成的。我不是说UML和相关的垃圾。在这种情况下,项目模型还包含自定义代码。
然后开发人员唯一需要关心的是模型。简单的体系结构更改可能导致数千个源代码行的即时修改。但一切都保持同步。
这是恕我直言的最佳方法。声音乌托邦?至少我知道它不是;)不久的将来会告诉你。
答案 14 :(得分:0)
这是一个工作流程问题。 ASP.NET是一个代码生成器。 XAML解析引擎在转换为MSIL之前实际生成C#。当代码生成器成为与开发工作流隔离的CodeSmith等外部产品时,必须特别注意保持项目的同步。例如,如果生成的代码是ORM输出,并且您对数据库模式进行了更改,则您要么必须完全放弃代码生成器,要么利用C#的容量来处理部分类(这样可以添加成员)和继承它的现有类的功能)。
我个人不喜欢发电机工作流程的隔离/ Alt-Tab特性;如果代码生成器不是我的IDE的一部分,那么我觉得它是一个kludge。一些代码生成器,如Entity Spaces 2009(尚未发布),比前几代生成器更加集成。
我认为可以在预编译例程中享受代码生成器的目的的灵丹妙药。虽然ASP.NET喜欢它,但是C#和其他.NET语言都缺乏这一点,这就是为什么SubSonic在ASP.NET上运行得非常好但不是很多。 SubSonic在正常的ASP.NET编译开始之前的构建时生成C#代码。
请求您的工具供应商(即Microsoft)更全面地支持预构建例程,以便可以使用元数据将代码生成器集成到解决方案的工作流程中,而不是手动管理为必须维护的外部输出代码文件孤立地。
乔恩
答案 15 :(得分:0)
我认为米切尔已经击中了它。 代码生成有其自己的位置。在某些情况下,让计算机为您完成工作更有效! 当代码更改的时间成本很小时,它可以让您自由地改变对特定组件实现的想法。当然,理解代码生成器的输出仍然很重要,但并非总是如此。 我们有一个关于我们刚刚完成的项目的示例,其中许多C ++应用程序需要通过命名管道与C#应用程序进行通信。我们最好使用定义消息的小而简单的文件,并为事务的每一方生成所有类和代码。当程序员正在处理问题X时,他们最不需要担心的是消息的实现细节和不可避免的缓存命中。
答案 16 :(得分:0)
第一批C ++编译器是代码生成器,它们吐出C代码(CFront)。
我不确定这是否是代码生成器的参数。
答案 17 :(得分:0)
它们可以作为一个拐杖,可以禁用你长期维持程序的能力。
答案 18 :(得分:0)
我使用我的生成与实体空间,我没有任何问题。如果我有一个模式更改,我只需重新生成类,这一切都很好。
答案 19 :(得分:0)
当你必须回来并且无法理解代码中发生的事情时,它可能真的成为可维护性的问题。因此,与易维护性相比,很多时候您必须权衡使项目快速完成的重要性
可维护性&lt;&gt;简单或快速的编码过程
答案 20 :(得分:0)
我们使用代码生成器来生成数据实体类,数据库对象(如触发器,存储过程),服务代理等。无论您看到许多重复代码遵循模式和涉及的大量手动工作,代码生成器都可以提供帮助。但是,你不应该过多地使用它,因为可维护性是一种痛苦。如果要重新生成它们,也会出现一些问题。
像Visual Studio这样的工具,Codesmith为大多数常见任务都有自己的模板,使这个过程更容易。但是,很容易自己推出。
答案 21 :(得分:0)
这是一个极具争议性的问题。就个人而言,我认为代码生成器非常糟糕,因为大多数代码都没有优化的垃圾代码。
然而,问题实际上是只有你能回答的问题。在许多组织中,开发时间比项目执行速度甚至可维护性更重要。
答案 22 :(得分:0)
它们就像任何其他工具一样。有些产品比其他产品效果更好,但用户应该知道何时使用它们。如果你试图用螺丝拧紧,锤子是一种可怕的工具。
答案 23 :(得分:0)
代码生成器并不错,但有时它们会在另一个解决方案存在的情况下使用(即,当一个对象数组更适合并在几行代码中完成时,实例化一百万个对象)。
另一种情况是它们使用不当或编码严重。太多人发誓代码生成器,因为他们由于错误而经历了糟糕的经历,或者他们误解了如何正确配置代码生成器。
但就其本身而言,代码生成器也不错。
- 亚当
答案 24 :(得分:0)
代码生成很糟糕,因为它使编程变得更加困难(IE,生成的代码很少或维护噩梦),但是当它们使编程更有效时它们就很好。
他们可能并不总能生成最佳代码,但根据您的需要,您可能会认为开发人员保存时间可以弥补一些小问题。
所有这一切,我对ORM代码生成器的最大抱怨是,如果架构发生变化,维护生成的代码可以是PITA。
答案 25 :(得分:0)
在某些(不是很多)情况下,它们很有用。例如,如果要根据数据库表中的查找类型数据生成类。