领域特定语言

本书是DSL领域的丰碑之作,由世界级软件开发大师和软件开发“教父”Martin Fowler历时多年写作而成,ThoughtWorks中国翻译。全面详尽地讲解了各种DSL及其构造方式,揭示了与编程语言无关的通用原则和模式,阐释了如何通过DSL有效提高开发人员的生产力以及增进与领域专家的有效沟通,能为开发人员选择和使用DSL提供有效的决策依据和指导方法。

译者序

2008 年,老马(Martin Fowler)在 Agile China 上做主旨发言,题目就是领域特定语言(Domain Specific Language, DSL)。老马提携后辈,愿意跟我合作完成这个演讲。而我呢,一方面,年少轻狂认为这个领域我也算个中好手,另一方面,也感激老马的信任和厚爱,就答应了。当时我已经知道老马在写一本关于这个主题的书,便跟他讨要原文来看。当时还没有成型的稿子,只有非常简略的草稿和博客片段。

2010 年年底,ThoughtWorks 技术战略委员会(ThoughtWorks Technology Advisor Board)在芝加哥开会。那时候,这本书的英文原版已然出版。晚上聚餐的时候,我心血来潮,跟老马说如果有机会,希望能将这本书翻译成中文,介绍给中国的开发者。老马听了很高兴,把最终定稿的电子版访问权限授予了我。

几个月后,同事刀哥(李剑)问我有没有兴趣参加这本书的翻译,我说当然有。后来回想起来,我还是上了刀哥的当,因为突然之间我就从参与翻译变成负责翻译了。

由于我手里已经有原稿的缘故,因此我们没有采用出版社提供的 Word 版本,而是在英文原稿上直接翻译。原稿除了文字部分之外,还有几千行代码。其中包括 XSTL、Ruby、C++、Java、图像处理脚本,甚至还有用于构建样书的 rake 脚本。惊讶之余, 作为程序员的求知欲也被激发出来了。在动手翻译之前,我们花了两天彻底了解这些代码的作用。然后就发现了这个惊人的秘密:

这是一本用领域特定语言写就的关于领域特定语言的书。

原文的文字部分是老马在 docbook 基础上定义的领域特定语言。这种语言除了在 docbook 的基础结构上定义了章节模板之外,还有两个专用结构:patternRef 和 codeRef 。

patternRef 用于处理模式名称在不同章节中的引用。本书分为两部分,前面的概念讲述部分和后面的模式部分。它耗时 3 年写就,在草稿阶段模式名称都未确定,各章节之间交叉引用很多。一旦出现模式名称改变,更新同步成本就很高。为此,老马定义了专有的语言结构,patternRef。所有对于模式的引用,都通过 patternRef 实现。由 patternRef 解析处理应该使用那个具体的名称。

这个巧妙的做法在后来的翻译中给我们带来了很大的困扰。因为 patternRef 会处理英语中的单复数,而中文不会有这样的情况。翻译稿中出现了大量的 s 和 es。最后还是通过修改 DSL 解析器里才解决了这个问题。

codeRef 则表示代码引用。这本书属于技术领域,其中会有大量代码示例;同一份代码示例会在不同章节中引用,一旦写法变化,就需要同步检查它在上下文内是否还能起到示范作用。老马先在示范代码的源代码中通过注释加入 XML 标注,把代码分解成一段段可引用的例子。因为是代码注释,所以不会影响源代码的编译、调试和重构。然后,再通过 codeRef,表明是哪个例子的哪段示例。最后,再通过 Ruby 和 XSLT,摘取对应的代码段,生成相应的文本。

我一直认为在澄清概念和发现模式上老马是有超能力的。通常会忘记他也是个 ThoughtWorker,而让做事情变得有趣,则是每个 ThoughtWorker 都有的超能力。

翻译这本书并不轻松,其中很多概念中文并无定译。为了呈现最好的结果,我们成立了一个翻译小组,包括熊节、郑烨、李剑、张凯峰、金明等有较多翻译经验的 ThoughtWorker 悉数在内。虽然如此,仍然难免疏漏 ,望读者不吝斧正。

徐昊

 ThoughtWorks 中国

免费下载

欢迎您 [DOWNLOAD] 或者购买完整版本,并为我们提出宝贵的建议。本迷你书大小为:5.7 M,您需要完整下载,方可正常阅读。

目录

译者序

前言

第一部分 叙述

  • 第 1 章入门例子 2
    • 1.1 哥特式建筑安全系统 2
    • 1.2 状态机模型 4
    • 1.3 为格兰特小姐的控制器编写程序 7
    • 1.4 语言和语义模型 13
    • 1.5 使用代码生成 15
    • 1.6 使用语言工作台 17
    • 1.7 可视化 20
  • 第 2 章 使用 DSL21
    • 2.1 定义 DSL21
      • 2.1.1DSL 的边界 22
      • 2.1.2 片段 DSL 和独立 DSL25
    • 2.2 为何需要 DSL25
      • 2.2.1 提高开发效率 26
      • 2.2.2 与领域专家的沟通 26
      • 2.2.3 执行环境的改变 27
      • 2.2.4 其他计算模型 28
    • 2.3DSL 的问题 28
      • 2.3.1 语言噪音 29
      • 2.3.2 构建成本 29
      • 2.3.3 集中营语言 30
      • 2.3.4 “一叶障目”的抽象 30
    • 2.4 广义的语言处理 31
    • 2.5DSL 的生命周期 31
    • 2.6 设计优良的 DSL 从何而来 32
  • 第 3 章实现 DSL34
    • 3.1DSL 处理之架构 34
    • 3.2 解析器的工作方式 37
    • 3.3 文法、语法和语义 39
    • 3.4 解析中的数据 39
    • 3.5 宏 41
    • 3.6 测试 DSL42
      • 3.6.1 语义模型的测试 42
      • 3.6.2 解析器的测试 45
      • 3.6.3 脚本的测试 49
    • 3.7 错误处理 50
    • 3.8DSL 迁移 51