DSL 问答
2008年9月9日
有人让我为非技术人员整理一份关于 DSL 的讨论。 也许我读了太多 Stephen O'Grady 的文章,但我有一种无法抗拒的冲动,想用问答的方式来做这件事。 所以就这样吧。
什么是领域特定语言?
领域特定语言 (DSL) 是一种表达能力有限的计算机编程语言,专注于特定领域。 你听说过的大多数语言都是通用语言,它们可以处理你在软件项目中遇到的大多数事情。 每种 DSL 只能处理系统的一个特定方面。所以你不会用 DSL 编写整个项目?
不会。 大多数项目将使用一种通用语言和几种 DSL。它们是一个新概念吗?
一点也不。 自 Unix 系统早期以来,DSL 就一直在 Unix 圈子中广泛使用。 Lisp 社区经常谈论用 Lisp 创建 DSL,然后使用 DSL 来实现逻辑。 大多数 IT 项目都使用几种 DSL——你可能听说过 CSS、SQL、正则表达式之类的东西。那么为什么它们现在会引起这么多关注呢?
可能是因为 Ruby 和 Rails。 作为一种语言,Ruby 具有许多特性,使其易于开发 DSL,并且参与 Ruby 社区的人们已经从其他地方熟悉这种方法,因此他们利用了这些特性。 特别是 Rails 使用了几种 DSL,这些 DSL 在使其易于使用方面发挥了重要作用。 这反过来又鼓励更多人接受这些想法。
另一个原因是许多 Java 和 C# 系统需要以更动态的方式定义它们的一些行为。 这导致了难以理解的复杂 XML 文件,这反过来又导致人们再次探索 DSL。
那么 DSL 可以与 Ruby 以外的语言一起使用吗?
是的,正如我所说,DSL 的存在时间比 Ruby 长得多。 Ruby 具有简洁的语法和元编程特性,使其比 C# 和 Java 等语言更容易创建更优雅的内部 DSL。 但是 Java 和 C# 中也有一些有用的内部 DSL。内部 DSL 和外部 DSL 之间有什么区别?
内部 DSL 只是主机语言中编写代码的一种特殊习惯用法。 因此,Ruby 内部 DSL 就是 Ruby 代码,只是以特定的风格编写,使其更具语言感。 因此,它们通常被称为流畅接口或嵌入式 DSL。 外部 DSL 是一种完全独立的语言,它被解析为主机语言可以理解的数据。为什么人们对 DSL 感兴趣?
我认为 DSL 有两个主要优点。 最常见的好处是它们使某些类型的代码更容易理解,这使得修改起来更容易,从而提高了程序员的生产力。 这本身就很有价值,而且相对容易实现。
然而,最有趣的好处是,精心设计的 DSL 可以被业务人员理解,从而使他们能够直接理解实现其业务规则的代码。
那么这就是关键——业务人员自己编写规则?
总的来说,我不这么认为。 创建一个允许业务人员编写自己的规则的环境需要做很多工作。 你必须制作一个舒适的编辑工具、调试工具、测试工具等等。 通过做足够多的工作,让业务人员能够阅读规则,你就可以获得面向业务的 DSL 的大部分好处。 然后,他们可以审查规则的准确性,与开发人员讨论规则,并起草更改以供开发人员正确实施。 使 DSL 具有业务可读性比业务可写性要容易得多,但可以获得大部分好处。 有时值得努力使 DSL 具有业务可写性,但这是一个更高级的目标。你需要特殊的(即昂贵的)工具吗?
一般来说,不需要。 内部 DSL 只是使用你已经在使用的编程语言的常规工具。 外部 DSL 确实需要你使用一些特殊的工具——但这些工具都是开源的,而且非常成熟。 这些工具最大的问题是大多数开发人员都不熟悉它们,并且认为它们比实际使用起来更难(糟糕的文档加剧了这个问题)。
然而,即将出现一些例外情况。 这些工具我称之为 语言工作台。 这些工具允许你更轻松地定义 DSL,并为它们提供复杂的编辑器。 这样的工具使得制作业务可写的 DSL 变得更加可行。
那么,这是对在没有编程(或程序员)的情况下开发软件的梦想的重复吗?
那是 COBOL 的意图,我认为没有任何理由认为 DSL 会在 COBOL(以及其他许多失败的地方)取得成功。 我认为重要的是,DSL 允许业务人员和开发人员更有效地协作,因为他们可以讨论一组共同的精确规则,这些规则就是可执行代码。我什么时候应该考虑制作 DSL?
当你正在查看具有丰富业务规则或工作流的系统方面时。 编写良好的 DSL 应该允许客户了解系统运行所依据的规则。这会不会导致人们难以学习的各种语言?
我们已经有了程序员必须学习的各种框架。 这是可重用软件的必然结果,这是我们能够处理当今软件必须做的所有事情的唯一方法。 从本质上讲,DSL 只不过是框架上的一个花哨的外观。 因此,与已经存在的复杂性相比,它们几乎没有增加任何复杂性。 事实上,好的 DSL 应该通过使这些框架更易于使用来使事情变得更好。但是人们不会创造很多糟糕的 DSL 吗?
当然,就像人们创建糟糕的框架一样。 但我还是要再次强调,与糟糕框架的成本相比,糟糕的 DSL 不会造成太多额外的损害。