基本信息
- 原书名:Domain-Specific Languages
- 原出版社: Addison-Wesley Professional; 1 edition
- 作者: (英)Martin Fowler
- 译者: ThoughtWorks中国
- 丛书名: 华章程序员书库
- 出版社:机械工业出版社
- ISBN:9787111413059
- 上架时间:2013-3-22
- 出版日期:2013 年3月
- 开本:16开
- 页码:464
- 版次:1-1
- 所属分类:计算机 > 软件与程序设计 > 综合 > 高级程序语言设计

编辑推荐
DSL领域的丰碑之作,软件开发“教父”Martin Fowler历时多年的心血结晶,ThoughtWorks中国翻译。
全面详尽地讲解各种DSL及其构造方式,揭示与编程语言无关的通用原则和模式,阐释如何通过DSL有效提高开发人员的生产力以及增进与领域专家的有效沟通。
内容简介
计算机书籍
《领域特定语言》是DSL领域的丰碑之作,由世界级软件开发大师和软件开发“教父”Martin Fowler历时多年写作而成,ThoughtWorks中国翻译。全面详尽地讲解了各种DSL及其构造方式,揭示了与编程语言无关的通用原则和模式,阐释了如何通过DSL有效提高开发人员的生产力以及增进与领域专家的有效沟通,能为开发人员选择和使用DSL提供有效的决策依据和指导方法。
全书共57章,分为六个部分:第一部分介绍了什么是DSL,DSL的用途,如何实现外部DS和内部DSL,如何生成代码,语言工作台的使用方法;第二部分介绍了各种DSL,分别讲述了语义模型、符号表、语境变量、构造型生成器、宏和通知的工作原理和使用场景;第三部分分别揭示分隔符指导翻译、语法指导翻译、BNF、易于正则表达式表的词法分析器、递归下降法词法分析器、解析器组合子、解析器生成器、树的构建、嵌入式语法翻译、内嵌解释器、外加代码等;第四部分介绍了表达式生成器、函数序列、嵌套函数、方法级联、对象范围、闭包、嵌套闭包、标注、解析数操作、类符号表、文本润色、字面量扩展的工作原理和使用场景;第五部分介绍了适应性模型、决策表、依赖网络、产生式规则系统、状态机等计算模型的工作原理和使用场景;第六部分介绍了基于转换器的代码生成、模板化的生成器、嵌入助手、基于模型的代码生成、无视模型的代码生成和代沟等内容。
作译者
目录
译者序
前言
第一部分 叙 述
第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
译者序
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中国
前言
我写这本书就是为了改变这个现状。我希望通过本书介绍的大量DSL技术,让你有足够的信息来做出决策:是否在工作中使用DSL,以及选择哪一种DSL技术。
造成DSL流行的原因有很多,我只着重强调两点:首先, 提升开发人员的生产力;其次,增进与领域专家之间的沟通。如果DSL选择得当,就可以使一段复杂的代码变得清晰易懂,在使用这段代码时提高程序员的工作效率。同时,如果DSL选择得当,就可以使一段普通的文字既可以当做可执行的软件,又可以充当功能描述,让领域专家能理解他们的想法是如何在系统中得到体现的,开发者和领域专家的沟通也会更加顺畅。增进沟通比起工作效率提升困难了一些,但带来的效果却更为显著。因为它可以帮助我们打通软件开发中最狭窄的瓶颈─程序员和客户之间的沟通。
我不会片面夸大DSL的价值。我常常说,无论你什么时候谈到DSL的优缺点,你都可以考虑把“DSL”换成“库”。实 际上,大多数DSL都只是在一个框架或者库上又加了薄薄的一层外壳。于是,DSL的成本和收益往往会比人们预想的要小,但也未曾得到过充分的认识。掌握良好的技术可以大大降低构造DSL的成本,我希望这本书可以帮你做到这一点。这层外壳虽薄,却也实用,值得一试。
为什么现在写这本书
DSL已问世很长时间,但近些年来,它们掀起了一股流行风潮。与此同时,我决定用几年的时间写这本书。为什么呢?虽然我并不知道自己能否给这股风潮下一个权威的定义,但是可以分享一下自己的观点。
在千禧年到来的时候,编程语言界─至少在我的企业软件世界里─隐约出现了一种颇具统治性的标准。先是 Java,它在几年的时间里风光无限。即使后来微软推出的C#挑战了Java的统治地位,但这个新生者依然是一门跟Java很相似的语言。新时代的软件开发被编译型的、静态的、面向对象的、语法格式跟C类似的语言统治着(甚至连VB都被迫变得尽可能具有这些性质)。
然而人们很快发现,并不是所有的事情都能在Java/C#的霸权下运作良好。有些重要的逻辑用这些语言无法很好实现,这导致了XML配置文件的兴起。不久之后,有程序员开玩笑说,他们写的XML代码比Java/C#代码都多。这固然有一部分原因是想在运行时改变系统行为,但也体现出人们的另外一个想法:用更容易定制的方式表达系统行为的各个方面。虽然XML噪音很多,但确实可以让你定义自己的词汇,而且提供了非常强大的层次结构。
不过后来人们实在无法忍受XML那么多的噪音了。他们抱怨尖括号刺伤了他们的双眼。他们希望一方面能够享受XML 配置文件带来的好处,另一方面又不用承受XML的痛苦。
我们的故事到现在讲了一半,这个时候Ruby on Rails横空出世,耀眼的光芒让一切都褪尽了颜色。无论Rails这个实用平台在历史上会占据什么样的位置(我觉得这确实是个优秀的平台),它都已经给人们对于框架和库的认识带来了深远的影响。Ruby社区有一个很重要的做事方式:让一切显得更加连贯。换句话说,在调用库的时候,就像用一门专门的语言进行编程一样。这不禁让我们回想起一门古老的编程语言:Lisp。通过它我们也看到了Java/C#这片坚硬的土地上绽开的花朵:连贯接口(fluent interface)在这两门语言中都变得流行起来,这大概要归功于JMock和 Hamcrest的创始人的不断努力。
回头看看这一切,我发现这里面有知识壁垒。有的时候,使用定制的语法会更容易理解,实现也不难,人们却用了XML;有的时候,使用定制的语法会简单很多,人们却把Ruby用得乱七八糟;有的时候,本来在他们常用的语言中使用连贯接口就可以轻易实现的事情,人们非要使用解析器。
我觉得这些事情都是因为存在知识壁垒才发生的。经验丰富的程序员对DSL的相关技术所知寥寥,没法对使用哪一项技术做出明智的判断。我对打破这个壁垒很感兴趣。
为什么DSL很重要
本书2.2节会讲述更多细节,不过我觉得需要学习DSL(以及本书中提到的其他技术)的原因主要有两个。
第一个原因是提升程序员的生产力。先看下面这段代码:
input =~ /\d{3}-\d{3}-\d{4}/
你会认出这是个正则表达式匹配,也许你还知道它匹配的是什么。正则表达式常常由于过于费解而遭受指责,但试想一下,如果你所能够使用的都是普通的正则控制代码,这段模式匹配会变成什么样子。而这段代码跟正则表达式相比,又是何等容易理解,容易修改?
DSL的第一个优势是它擅长在程序中的某些特定地方发挥作用,并且让它们容易理解,进而提高编写、维护的速度,也会减少bug。
DSL的第二个优势就不仅仅限于程序员的范畴了。因为DSL往往短小易读,所以非程序员也能看懂这些驱动他们重要业务的代码。把这些真实的代码暴露在理解该领域的人们面前,可以确保程序员和客户之间有非常顺畅的沟通渠道。
当人们谈论这类事情的时候,他们常说DSL可以让你不再需要程序员。我对这一论调极度不认同,毕竟那是说COBOL的。不过也确实有些语言是由那些自称不是程序员的人来用的,比如CSS。对这种语言来说,读比写要重要得多。如果一个领域专家可以阅读并且理解核心业务代码中的绝大部分,那他就可以跟写这段代码的程序员进行深入细节的交流。
书摘
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中国