你创建自己的代码生成器吗?

时间:2008-09-22 05:19:50

标签: code-generation

The Pragmatic Programmer提倡使用代码生成器。 您是否在项目中创建代码生成器?如果是的话,你用它们做什么?

26 个答案:

答案 0 :(得分:20)

在“实用程序员”中,Hunt和Thomas区分被动和主动代码生成器。

无源生成器只运行一次,然后编辑结果。

活动生成器根据需要经常运行,您永远不应该编辑结果,因为它将被替换。

IMO,后者更有价值,因为他们接近DRY(不重复自己)的原则。

如果程序的输入信息可以分为两部分,那么很少改变的部分(A)(如元数据或DSL),以及每次运行程序时不同的部分(B)(实时输入),你可以编写一个只接受A作为输入的生成器程序,并写出一个只接受B作为输入的ad-hoc程序。 (另一个名称是部分评估。)

生成器程序更简单,因为它只需要通过输入A,而不是A和B。但是,它不必非常快,因为它不经常运行,并且它不必关心内存泄漏

ad-hoc程序更快,因为它不必涉及几乎总是相同的输入(A)。它更简单,因为它只需要对输入B做出决定,而不是A和B.

生成的ad-hoc程序非常易读,因此您可以更轻松地找到其中的任何错误。一旦你从生成器中删除了错误,它们就会永远消失。

在我参与的一个项目中,一个团队设计了一个复杂的数据库应用程序,其设计规格为2英寸厚,实施时间很长,充满了对性能的担忧。通过编写代码生成器,两个人在三个月内完成了这项工作,源代码列表(在C中)厚度约为半英寸,生成的代码速度非常快,不会成为问题。临时计划每周重建一次,费用很低。

所以活动代码生成,,当你可以使用时,是一个双赢的。并且,我认为这正是编译器所做的事情并非偶然。

答案 1 :(得分:9)

在硬件设计中,在“堆栈”的多个级别执行此操作是相当常见的做法。例如,我编写了一个代码生成器,用于发出各种宽度,拓扑结构以及DMA引擎和交叉开关结构的Verilog,因为表达此参数化所需的结构在合成和仿真工具流程中尚未成熟。

将逻辑模型一直发布到布局数据也是常规的,可以通过算法表达和生成非常规则的事物,如SRAM,缓存和寄存器文件结构。

我还花了相当多的时间编写一个代码生成器,它将对片上系统中的所有寄存器进行XML描述,然后发出HTML(是的,是的,我知道XSLT,我刚刚发现以编程方式发送它以提高时间效率),Verilog,SystemVerilog,C,汇编等对不同团队(前端和后端ASIC设计,固件,文档等)的“数据”进行“查看”使用(并通过这个单一的XML“代码库”使它们保持一致)。这算了吗?

人们也喜欢为例如编写代码生成器简单描述非常常见的东西,比如有限状态机,并机械地输出更详细的命令式语言代码,以便有效地实现它们(例如转换表和遍历代码)。

答案 2 :(得分:8)

代码生成器如果在没有正确论证的情况下广泛使用,会使代码不易理解并降低可维护性(顺便说一下,动态SQL也是如此)。就个人而言,我正在将它与一些ORM工具一起使用,因为它们在这里的使用大多是显而易见的,有时用于搜索器 - 解析器算法和语法分析器之类的东西,这些算法最近并不是为了“手工”而设计的。欢呼声。

答案 3 :(得分:6)

我们使用代码生成器来生成数据实体类,数据库对象(如触发器,存储过程),服务代理等。无论您看到许多重复代码遵循模式和涉及的大量手动工作,代码生成器都可以提供帮助。但是,你不应该过多地使用它,因为可维护性是一种痛苦。如果要重新生成它们,也会出现一些问题。

像Visual Studio这样的工具,Codesmith为大多数常见任务都有自己的模板,使这个过程更容易。但是,很容易自己推出。

答案 4 :(得分:5)

创建一个从规范生成代码的代码生成器通常很有用 - 通常是具有常规表格规则的代码。它通过拼写错误或遗漏减少了引入错误的可能性。

答案 5 :(得分:3)

是的, 我为AAA协议Diameter(RFC 3588)开发了自己的代码生成器。 它可以为描述直径应用程序语法的XML文件中的直径消息生成结构和Api。

这大大缩短了开发完整直径界面的时间(例如SH / CX / RO等)。

答案 6 :(得分:2)

为项目编写自己的生成器效率不高。相反,使用T4,CodeSmith和Zontroy等生成器。

T4更复杂,您需要了解.Net编程语言。您必须逐行编写模板,并且必须自己完成数据关系操作。您可以在Visual Studio上使用它。

CodeSmith是一个功能工具,有很多模板可供使用。它基于T4,编写自己的temlate需要花费太多时间,因为它在T4中。有试用版和商业版。

Zontroy是一款具有用户友好用户界面的新工具。它有自己的模板语言,易于学习。有一个在线模板市场,它正在发展。即使您可以提供模板并在市场上在线销售。 它有免费和商业版本。即使是免费版也足以完成一个中等规模的项目。

答案 7 :(得分:2)

在我看来,一个好的编程语言不需要代码生成器,因为内省和运行时代码生成将是语言的一部分,例如在python元类和新模块等。

答案 8 :(得分:2)

代码生成器通常会在长期使用中生成更难以管理的代码。

然而,如果绝对必须使用代码生成器(eclipse VE用于swing开发是我有时使用的),那么请确保您知道正在生成什么代码。相信我,你不希望你的应用程序中有你不熟悉的代码。

答案 9 :(得分:1)

你要找几个人?我创造了两个主要的和很多次要的。第一个主要的程序允许我生成程序1500行程序(给予或接受),这些程序具有强烈的家族相似性,但与数据库中的不同表格相协调 - 并且可以快速,可靠地完成。

代码生成器的缺点是,如果生成的代码中存在错误(因为模板包含错误),那么需要做很多修复。

然而,对于那些需要进行大量近似重复编码的语言或系统,一个好的(足够的)代码生成器是一个福音(更多的是一个恩惠而不是'狗狗')。

答案 10 :(得分:1)

可能会有很多代码生成器,但是我总是创建自己的代码生成器以使代码更容易理解并适合我们正在使用的框架和指南

答案 11 :(得分:1)

我有自己的代码生成器,我针对SQL表运行。它生成用于访问数据,数据访问层和业务逻辑的SQL过程。它在标准化我的代码和命名约定方面做了很多奇迹。因为它需要数据库表中的某些字段(例如id列和更新的datetime列),所以它也有助于标准化我的数据设计。

答案 12 :(得分:1)

我最近对发电机的需求是一个从硬件读取数据并最终将其发布到“仪表板”UI的项目。中间是几个数据点的模型,属性,演示者,事件,接口,标志等。我编写了几个数据点的框架,直到我对我能够接受设计感到满意为止。然后,在一些精心放置的注释的帮助下,我将“generation”放在visual studio宏中,调整并清理宏,将数据点添加到宏中的函数来调用生成 - 并节省了几个繁琐的小时(天) ?)最后。

不要低估宏的力量:)


我现在也试图了解CodeRush自定义功能,以帮助我满足更多本地生成要求。如果在生成代码块时需要动态决策,那里有强大的功能。

答案 13 :(得分:1)

我们为所有新代码使用生成器来帮助确保遵循编码标准。

我们最近用CodeSmith替换了我们的内部C ++生成器。我们仍然需要为该工具创建模板,但似乎不需要自己维护该工具。

答案 14 :(得分:0)

我无法想到我们需要从头开始创建自己的代码生成器的任何项目,但有几个我们使用预先存在的生成器。 (我已经使用Antlr和Eclipse Modeling Framework在java中为企业软件构建解析器和模型。)使用其他人编写的代码生成器的好处是作者倾向于成为该领域的专家并解决了问题我甚至都不知道存在。这节省了我的时间和挫折。

所以尽管我可以编写解决手头问题的代码,但我可以更快地生成代码,并且很有可能它比我写的任何东西都要少。

答案 15 :(得分:0)

如果您不打算编写代码,您是否会对其他人生成的代码感到满意?

从长远来看,编写自己的代码或代码生成器的时间和$$$都会更便宜吗?

我编写了一个代码生成器,它将构建100个类(java),它将以DTD或模式兼容的方式从数据库输出XML数据。代码生成通常是一次性的事情,然后代码将通过各种业务规则等进行智能化。输出是针对一个相当迂腐的银行。

答案 16 :(得分:0)

代码生成器可以解决编程语言限制问题。我个人更喜欢反射而不是代码生成器,但我同意代码生成器更灵活,并且在运行时期间代码显然更快。我希望,未来版本的C#将包含某种DSL环境。

答案 17 :(得分:0)

是的,我必须保留一些。 CORBA或其他一些对象通信风格的接口可能是我首先想到的一般事情。您有对话定义是由您要讨论的接口提供给您的,但您仍然需要在代码中构建这些对象。构建和运行代码生成器是一种相当常规的方法。这可能会成为一个相当冗长的编译,只是为了支持一些传统的通信渠道,并且因为有很大的趋势将包装器放在CORBA周围以使其变得更简单,所以事情变得更糟。

一般情况下,如果你有大量的结构,或者只是需要快速改变你需要使用的结构,但你无法通过元数据来处理构建对象的性能,那么你就可以编写代码生成器了。

答案 18 :(得分:0)

我使用的唯一代码生成器是webservice解析器。我个人远离代码生成器,因为新员工或交付后的单独团队存在维护问题。

答案 19 :(得分:0)

我编写自己的代码生成器,主要是在T-SQL中,在构建过程中调用它们。

基于元模型数据,它们生成触发器,日志记录,C#const声明,INSERT / UPDATE语句,数据模型信息以检查应用程序是否在预期的数据库模式上运行。

我仍然需要编写一个表单生成器来提高生产力,增加规范和减少编码;)

答案 20 :(得分:0)

我创建了一些代码生成器。我有一个用于SQL存储过程的被动代码生成器,它使用模板。这生成了90%的存储过程。

由于我们切换到Entity Framework,因此我在visual studio中使用T4(Text Template Transformation Toolkit)创建了一个活动的代码生成器。我用它来为我们的实体创建基本的存储库部分类。工作得很好,节省了一堆编码。我还使用T4来装饰具有某些属性的实体类。

答案 21 :(得分:0)

我使用EMF - Eclipse Modeling Framework提供的代码生成功能。

答案 22 :(得分:0)

在许多情况下,代码生成器非常有用,尤其是在从一种格式映射到另一种格式时。我已经完成了IDL到C ++的代码生成器,到OO类型的数据库表,以及编组代码等等。

我认为作者试图提出的观点是,如果您是开发人员,您应该能够让计算机为您工作。生成代码只是一项自动化的明显任务。

我曾经和一个坚持他会手动进行IDL到C ++映射的人一起工作过。在项目开始时,他能够跟上,因为我们其他人都试图弄清楚要做什么,但最终他成了瓶颈。我在Perl中做了一个代码生成器,然后我们可以在几分钟内完成他的“工作”。

答案 23 :(得分:0)

根据程序转换查看我们的"universal" code generator

我是建筑师和关键实施者。 值得注意的是,使用此生成器生成此生成器的很大一部分。

答案 24 :(得分:0)

在嵌入式系统中,有时您需要在闪存中使用大块二进制数据。例如,我有一个采用包含位图字体字形的文本文件,并将其转换为.cc / .h文件对,声明有趣的常量(如第一个字符,最后一个字符,字符宽度和高度),然后将实际数据作为一个很大的static const uint8_t[]

尝试在C ++本身做这样的事情,所以字体数据会在没有第一遍的情况下在编译时自动生成,这将是一种痛苦,而且很可能难以理解。手动编写.o文件是不可能的。因此,打破方格纸,手动编码为二进制,并输入所有内容。

恕我直言,这种事情是代码生成器的用途。 永远不要忘记计算机适合您,而不是相反。

顺便说一句,如果您使用生成器,总是在每个生成的文件的开头和结尾都包含一些这样的行:

// This code was automatically generated from Font_foo.txt. DO NOT EDIT THIS FILE.
// If there's a bug, fix the font text file or the generator program, not this file.

答案 25 :(得分:0)

我们在项目中使用 Telosys 代码生成器:http://www.telosys.org/

我们创建它是为了减少CRUD屏幕,文档等周期性任务的开发持续时间......

对我们来说,最重要的是能够自定义生成器的模板,以便在必要时创建新的生成目标并自定义现有模板。这就是为什么我们还创建了一个模板编辑器(用于Velocity .vm文件)。 它适用于Java / Spring / AngularJS代码生成器,可以适应其他目标(PHP,C#,Python等)