《领域特定语言》一3.8 DSL迁移

简介: 本节书摘来自华章出版社《领域特定语言》一书中的第3章,第3.8节,作者 (英)Martin Fowler,更多章节内容可以访问云栖社区“华章计算机”公众号查看

3.8 DSL迁移

DSL拥趸们应该警惕的一个风险是“先编写,后使用”的想法。同其他软件一样,成功的DSL需要不断演化。也就是说,以早期版本DSL编写的脚本可能无法在新版上运行。
DSL的诸多属性(无论好坏)同程序库完全一样,这一点也不例外。如果从别人那里得到一个程序库,基于它编写一些代码,他们升级了程序库,我们可能最终就卡在那里。DSL并不会真正改变这一点;本质上DSL定义的就是已发布接口(published interface),我们不得不自行处理这个后果。
在重构 [Fowler Refactoring]一书里,我开始使用已发布接口这个术语。已发布接口和更一般的“公共”接口的不同之处在于,前者由其他团队编写的代码使用。所以,修改已发布接口是很困难的,因为他们无法重写调用代码。修改已发布DSL对于内部DSL和外部DSL都是个问题。如果DSL尚未发布,而且相关语言有自动化重构工具,修改内部DSL还容易一点。
解决DSL修改问题的一种方式是,提供工具,自动把DSL从一个版本迁移到另一个版本。这些工具可以在升级时运行,也可以在尝试运行旧版脚本时自动运行。
有两种方式实现迁移。一种是增量迁移的策略,这种方式本质上同人们处理数据库设计的演化所采用的想法是一致的。我们会创建一个程序,对DSL定义的每个变化,都可以自动将旧版脚本迁移到新版本上。采用这种方式,当发布新版DSL时,还要提供一个脚本,迁移使用DSL的代码库。
对于增量迁移,有一点很重要,就是要让每一个修改尽可能小。想象一下,我们要从版本1升级到版本2,DSL定义有10处修改。在这种情况下,不要只创建一个“从版本1到版本2”的迁移脚本;相反,可以创建至少10个脚本。一次修改DSL定义的一个特性,为每个修改编写一个迁移脚本。将修改拆分为更多步骤,某些特性甚至要多于一步(因此要多于一个迁移脚本),你会发现这种做法非常有用。听起来,这种做法比单一脚本要多做一些工作,但重点在于,如果迁移都很小,脚本写起来会容易得多,而且把多个脚本串起来也很容易。所以,写10个脚本反而比写一个更快。
另一种方式是基于模型的迁移。这种策略可以与“语义模型”(第11章)配合使用。有了基于模型的迁移,我们的语言就可以支持多个解析器,每个发布版对应一个(当然,我们只会为版本1、2这样的大版本这样做,而不会理会中间步骤)。每个解析器都会组装语义模型。当采用语义模型时,解析器的行为相当简单。所以,有多个解析器也不是什么麻烦事。之后,针对所处理脚本的版本,可以运行相应的解析器。这种方式可以处理多个版本,但并不迁移脚本。为了处理迁移,可以根据语义模型编写一个生成器,生成DSL脚本。采用这种方式,可以对版本1的脚本运行解析器,组装语义模型,然后用生成器生成版本2的脚本。
基于模型的方式有一个问题,它很容易丢掉一些与语义无关但脚本编写者希望保留的东西。最明显的一个例子就是注释。如果解析器太过聪明,这个问题就会越发严重。以这种方式进行迁移的需求,会促使解析器写得更加简单,这是好事。
如果DSL的修改够大,很可能无法从版本1的脚本直接转换为版本2的语义模型。在这种情况下,可能需要保留版本1的模型(或者中间模型),给予它生成版本2脚本的能力。
对这两种方式,我没有很强烈的倾向。
迁移脚本可以由脚本程序员在需要的时候自己运行,或者让DSL系统自动运行。如果要自动运行的话,在脚本中记录它是哪个版本将会非常有用,这样,解析器可以很容易地检测到,并触发相应的迁移脚本。事实上,有一些DSL作者甚至强调说,DSL脚本上的版本信息是必需的,这样就可以更容易地检测出过时的DSL,以便进行脚本的迁移。虽然版本信息可能会给脚本添加一些噪音,但它基本上是不太会更改的东西。
当然,还有一个迁移选项,就是不迁移。保留版本1的解析器,让它组装版本2的模型。我们应该帮助人们进行迁移,如果他们需要更多特性,他们就会这么做。可以的话,直接支持旧脚本也未尝不可,这样,人们就可以按照自己的节奏去迁移。
虽然这样的技术很吸引人,但在实际中,是否值得这么做依然存疑。如我之前所说,这个问题同广为使用的程序库完全一样,自动迁移的策略没有多少人用。

相关文章
|
1月前
|
程序员 API C语言
在C++语言的标准I/O库
在C++语言的标准I/O库
10 0
|
XML SQL JSON
一杆到底:DSL 领域特定语言
一、DSL了解1、DSL介绍DSL(Domain Specific Language)是针对某一领域,具有受限表达性的一种计算机程序设计语言。 常用于聚焦指定的领域或问题,这就要求 DSL 具备强大的表现力,同时在使用起来要简单。说到DSL,大家也会自然的想到通用语言(如Java、C等)。为什么没有一种语言同时 兼具『简洁』和『业务表达』能力呢?从信息论本质上来讨论这个问题,每个语言的程序都可以抽
6005 0
一杆到底:DSL 领域特定语言
|
自然语言处理
Drools使用dsl语言
Drools使用dsl语言
455 0
|
开发框架 自然语言处理 前端开发
一种新的DSL生成和通用语言框架:pypy
本文关键字:DSL框架和自动化生成工具,pypy as dsl framework and jit framework
808 0
一种新的DSL生成和通用语言框架:pypy
|
XML 测试技术 数据格式
《领域特定语言》一第3章 实现DSL 3.1DSL处理之架构
本节书摘来自华章出版社《领域特定语言》一书中的第3章,第3.1节,作者 (英)Martin Fowler,更多章节内容可以访问云栖社区“华章计算机”公众号查看
1724 0
|
前端开发 JavaScript 测试技术
《领域特定语言》一3.6 测试DSL
本节书摘来自华章出版社《领域特定语言》一书中的第3章,第3.6节,作者 (英)Martin Fowler,更多章节内容可以访问云栖社区“华章计算机”公众号查看
1393 0
|
数据可视化 程序员 API
《领域特定语言》一2.2为何需要DSL
本节书摘来自华章出版社《领域特定语言》一书中的第2章,第2.2节,作者 (英)Martin Fowler,更多章节内容可以访问云栖社区“华章计算机”公众号查看
1750 0
|
测试技术 API
《领域特定语言》一2.5 DSL的生命周期
本节书摘来自华章出版社《领域特定语言》一书中的第2章,第2.5节,作者 (英)Martin Fowler,更多章节内容可以访问云栖社区“华章计算机”公众号查看
1029 0
|
XML SQL API
《领域特定语言》一第2章 使用DSL 2.1定义DSL
本节书摘来自华章出版社《领域特定语言》一书中的第2章,第2.1节,作者 (英)Martin Fowler,更多章节内容可以访问云栖社区“华章计算机”公众号查看
2049 0
|
测试技术