我越来越多地听到有关领域特定语言的说法,以及它们如何改变您对待业务逻辑的方式,并且我已经看到 Ayende 的博客文章 等等,但我从来没有真正明白为什么我要把我的业务逻辑从我在提供程序中使用的方法和情况中剔除。

如果您有一些使用这些东西的背景,那么您有机会用真正的外行术语来表达它:

  • 构建 DSL 到底意味着什么?
  • 您使用什么语言?
  • 在什么情况下使用 DSL 有意义?
  • 使用 DSL 有什么好处?
有帮助吗?

解决方案

当您需要将系统某些方面的控制权交给其他人时,DSL 非常有用。我在规则引擎中使用了它们,您可以在规则引擎中创建一种简单的语言,让技术含量较低的人员更容易使用它来表达自己,尤其是在工作流程中。

换句话说,不是让他们学习java:

DocumentDAO myDocumentDAO = ServiceLocator.getDocumentDAO();
for (int id : documentIDS) {
Document myDoc = MyDocumentDAO.loadDoc(id);
if (myDoc.getDocumentStatus().equals(DocumentStatus.UNREAD)) {
    ReminderService.sendUnreadReminder(myDoc)
}

我可以写一个 DSL,让我说:

for (document : documents) {
if (document is unread) {
 document.sendReminder
}

还有其他情况,但基本上,任何您可能想要使用宏语言、编写工作流程脚本或允许售后定制的地方 - 这些都是 DSL 的候选者。

其他提示

DSL 代表 领域特定语言 IE。专门为解决特定领域的问题而设计的语言。
例如,Markdown(用于编辑 SO 上的帖子的标记语言)可以被视为 DSL。

就我个人而言,我几乎在我正在从事的每个大型项目中都找到了 DSL 的一席之地。大多数情况下,我需要某种类似 SQL 的查询语言。另一种常见的用法是基于规则的系统,您需要某种语言来指定规则\条件。

在难以通过传统方式描述\解决问题的环境中,DSL 很有意义。

如果您使用 Microsoft Visual Studio,那么您已经在使用多种 DSL——Web 表单、winforms 等的设计界面。是DSL。类设计器是另一个例子。

DSL 只是一组(至少在理论上)在特定“领域”(即,进行开发)的工具。视觉布局)更简单、更直观、更高效。

就构建 DSL 而言,像 Ayende 这样的人写的一些内容与“文本解析”DSL 相关,让开发人员(或最终用户)将“自然文本”输入到应用程序中,应用程序解析文本并生成某种类型代码或基于它的输出。

您可以使用任何语言来构建您自己的 DSL。Microsoft Visual Studio 有很多可扩展点,以及模式和实践 “指导自动化工具包”视觉工作室 SDK 可以帮助您向 Visual Studio 添加 DSL 功能。

DSL 是自定义语言的基本编译器。可以在以下位置找到一个很好的“免费且开放”的开发工具: ANTLR. 。最近,我一直在研究这个 DSL 状态机语言 在新项目上使用。我同意上面 Tim Howland 的观点,即它们可以是让其他人自定义您的应用程序的好方法。

仅供参考,一本关于 DSL 的书正在编写中,作为 Martin Fowler 签名系列的一部分。

如果它与该系列中的其他书具有相同的标准,那么它应该是一本好书。

更多信息 这里

DSL 只是一个奇特的名字,可能有不同的含义:

  • Rails(Ruby 的东西)有时被称为 DSL,因为它添加了特殊的方法(并且也覆盖了一些内置的方法)来讨论 Web 应用程序

  • ANT、Makefile 语法等也是 DSL,但有自己的语法。这就是我所说的 DSL。

这种炒作的一个重要方面是:从语言的角度考虑您的应用程序确实有意义。您想在您的应用程序中谈论什么?这些应该是您的类和方法:

  1. 定义一种能够表达您的问题的“语言”(可以是本页其他人提出的真实语法,也可以是您喜欢的语言的类层次结构)。
  2. 用该语言解决您的问题。

DSL 基本上是创建您自己的小子语言来解决特定的领域问题。这是使用方法链解决的。点和括号是可选的语言有助于使这些表达看起来更自然。它也可以类似于构建器模式。DSL 本身并不是语言,而是一种应用于 API 的模式,以使调用更加不言自明。

吉斯就是一个例子, Guice 用户指南 http://docs.google.com/View?docid=dd2fhx4z_5df5hw8 下面有一些关于接口如何绑定到实现以及在什么上下文中的进一步描述。

另一个常见的例子是查询语言。例如:

NewsDAO.writtenBy("someUser").before("someDate").updateStatus("Deleted")

在实现中,想象每个方法返回一个新的 Query 对象,或者只是在内部更新自身。在任何时候,您都可以通过使用 rows() 来获取所有行或 updateSomeField 来终止链,就像我在上面所做的那样。两者都会返回一个结果对象。

我建议您也看看上面的 Guice 示例,因为每次调用都会返回一个带有新选项的新类型。一个好的 IDE 将允许您完成,并清楚地表明您在每个点上有哪些选项。

编辑:似乎许多人认为 DSL 是一种新的、简单的、单一用途的语言,有自己的解析器。我总是将 DSL 与使用方法链作为表达操作的约定联系起来。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top