本指南将向您显示:
之后,您将获得一系列资源以学习更多内容:书籍,网站,论文,屏幕录像。
这是有关领域特定语言的最完整资源。 我希望你会喜欢它!
只是一件事:在这里,我们尝试变得实用且易于理解。 如果您正在寻找正式的定义和理论讨论,这是不合适的地方。
什么是领域特定语言?
域特定语言是在特定域中执行以支持一组特定任务的语言。
您可能熟悉典型的编程语言(也称为通用编程语言或GPL)。 它们是足以创建各种程序的工具,但并不是真正针对任何事物。 它们就像锤子:如果您有足够的耐心和能力来适应它们,则足以胜任许多任务,但是在大多数情况下,使用更特定的工具会更好。 您可以使用锤子打开啤酒,这比使用诸如开瓶器之类的专用工具更加困难,风险更大并且导致结果更差。
语言是解决问题的工具,而领域特定语言是特定工具,可以很好地解决有限的问题。
好的,但是实际上这是什么意思呢? DSL看起来如何? 让我们看很多例子。
19个领域特定语言的示例
领域特定语言可以满足各种目的。 它们可以在不同的上下文中和由不同类型的用户使用。 一些DSL旨在供程序员使用,因此更具技术性,而其他DSL则供非程序员使用,因此它们使用的怪异概念和语法较少。
特定领域的语言可以是非常特定的,并且只能在公司内部使用。 我自己建立了几种此类DSL,但不允许共享。 相反,我可以列出数以百万计的人使用的公共DSL的几个示例。
1. DOT –定义图形的DSL
DOT是一种可以描述有向图或无向图的语言。
digraph graphname {
yellow -> orange -> red;
orange -> green;
}
根据该描述,可以生成表示这些曲线图的图像。 为此,请使用名为graphviz
的程序,该程序可与DOT语言一起使用。 从前面的示例中,您将获得以下信息:
该语言还允许定义节点的形状,其颜色和许多其他特征。 但是基础非常简单,几乎每个人都可以在几分钟内学会如何使用它。
2. PlantUML –绘制UML图的DSL
PlantUML可用于定义不同种类的UML图。 例如,我们可以定义一个序列图。
@startuml
actor MyUser
actor CustomerCare
database database
MyUser -> CustomerCare : Ask a refund
CustomerCare -> database : Verify the data
CustomerCare -> MyUser : Issue a refund
@enduml
从这个定义我们可以得到一张照片。
使用类似的语法,可以定义不同种类的图,例如类图或用例图。 使用文本DSL定义UML图具有多个优点:易于版本化,并且每个人都可以在没有特殊工具的情况下对其进行修改。 像这样的DSL可以在会议期间用于支持讨论:由于与会者争辩说,可以快速定义不同的图表,并单击一下即可生成相应的图像。
3. Sed –定义文本转换的DSL
在类似UNIX的操作系统(Linux,Mac,BSD等)上,有一组命令行工具,每个命令行工具都接受自己格式的指令。 可以将这种格式视为DSL,它可以指定要执行的任务。 例如, sed使用其自己的DSL执行指示的文本转换。
您要用“约翰”代替“杰克”吗?
s/Jack/John/g
还是要从第10行删除文件的所有行,直到找到单词“ stophere”?
10,/stophere/d
提高了熟练使用这种DSL所需的技术水平。 但是,许多高级计算机用户可以学习在文件上执行常见操作的基本知识。 他们每天可能需要做的小事情,目前正在手动做。 例如,您可能拥有包含诸如“ {FIRST_NAME}”之类的占位符的电子邮件模板,并使用此命令之一用适当的测试替换它们。
4. Gawk –用于打印和处理文本的DSL
与sed一样,gawk是另一个UNIX实用程序,它以其自己的语言接受命令。 例如,您可以打印给定文件的所有超过80个字符的行:
length($0) > 80
或计算文件中的行数:
END { print NR }
UNIX的哲学是使用几个或这些小工具,并将它们组合起来以执行最令人惊奇和最复杂的任务。 例如,您可以获取一个输入文件,使用sed对其进行转换,然后使用gawk打印选定的零件。
5. Gherkin –定义功能测试的DSL
Gherkin是用于定义功能测试的DSL。 它具有非常灵活的语法,使其看起来几乎像自由文本。 基本上,开发人员,分析师和客户可以围坐在桌子旁并定义一些方案。 然后这些场景将作为测试可执行,以验证应用程序是否符合期望。
这是我们如何定义从ATM提款的期望:
Scenario: Verify withdraw at the ATM works correctly
Given John has 500$ on his account
When John ask to withdraw 200$
And John inserts the correct PIN
Then 200$ are dispensed by the ATM
And John has 300$ on his account
我真的很喜欢这种DSL,因为使用它的门槛很低。 但是,此DSL需要开发人员使用GPL定义一些代码。 实际上,开发人员如何定义特定的命令,例如:“ {name}的帐户中有{amount} $”,并在为项目选择的GPL中定义执行该命令的代码(Ruby,Java或其他支持的)。 一旦开发人员创建了特定于所需应用程序的命令,所有用户都可以在定义其功能测试时使用它们。 也可以用另一种方式开始:首先,根据需要编写方案,尝试捕获需求,然后再由开发人员将每个命令映射到GPL中的相应功能。
换句话说,此DSL非常适合将真实代码隐藏在每个人都可以理解且每个人都可以做出贡献的表面下。 与我们向他展示与这些命令相对应的数百行Java,对我们来说,与我们展示的示例相比,坐在桌旁与银行代表进行讨论要好得多。
6.网站规范–用于功能Web测试的DSL
Gherkin不是唯一用于定义测试的DSL。 网站规范可用于定义特定于Web应用程序的功能测试。
在这里,我们定义了如何在特定网站上导航以及我们希望找到的内容。
Open $url
Clock on create
# Select a store
Within card-panel-store
Select `[date-test=stores] label`
Remember test as $StoreName
Click
Select button continue
!Class should not contain "disabled"
Click
Select element `.preview-value`
Property text should be $StoreName
在这种情况下,开发人员无需定义命令到GPL的转换,因为这种语言的用户会使用特定域的命令,例如解释程序知道如何执行的“点击”。 现在,只需进行最少的培训,任何人都可以描述与网站的特定交互作用以及预期的结果。 很整洁吧?
7. SQL –数据库
您可能听说过SQL。 它是一种语言,用于定义如何从关系数据库中插入,修改或提取数据。 让我们从STATS表中获取一些统计信息:
SELECT MAX(TEMP_F), MIN(TEMP_F), AVG(RAIN_I), ID
FROM STATS
GROUP BY ID;
当然,您不希望普通的Joe能够编写复杂的查询:SQL不是一种琐碎的语言,它需要一些时间来掌握。 但是,您不需要经过培训就可以学习SQL。 实际上,许多DBA都不是开发人员。 也许Joe不应以对数据库的写访问权受到信任,但他可以获取读访问权限并编写简单的查询来回答自己的问题,而不必问别人并等待获得答案。 假设他需要知道亚特兰大八月的最高气温:
SELECT MAX(value) FROM TEMPERATURES WHERE city="Atlanta" AND month="August";
也许Joe永远不会达到DBA的水平,但是他可以学习一些基本查询并使其适应他的需求,从而使他变得更加独立,并使他的同事专注于他们的工作而不是帮助他。
8. HTML –网站布局
我真的希望您听说过这种定义文档的相当成功的语言。 令人惊讶的是,我们可以在20年前定义HTML页面,当时大多数人将台式计算机连接到分辨率为640×480像素的显示器,现在这些页面可以在我们的智能手机上运行的浏览器中呈现。 我想这是DSL可以实现的一个很好的例子。
<html>
<head>
<title>My beautiful page</title>
</head>
<body>
<div id="main">
<h1>Really interesting title!</h1>
<p>And the content is even better!</p>
<div>consid
</body>
</html>
请注意,HTML实际上是关于定义文档的:它们的结构和包含的信息。 然后,同一文档在台式计算机,平板电脑或智能手机上的呈现方式有所不同。 同一文档的消费方式与残疾人不同。 针对视力障碍者的特定浏览器通过阅读内容来帮助他们使用HTML定义的文档,并支持导航到文档的不同部分。
9. CSS –样式
级联样式表语言定义了用于可视化文档的样式。 我们可以使用它来定义HTML文档在屏幕上的显示方式或打印时的显示方式。
p.center {
text-align: center;
color: red;
}
@page :left {
margin: 0.5cm;
}
@page :right {
margin: 0.8cm;
}
CSS掌握起来并不是一件容易的事,但是许多有基本的编程知识或根本没有编程知识的人都可以使用它来更改网页的外观。 该DSL在使网站设计民主化方面发挥了重要作用。
10. XML –数据编码
几年前,XML似乎是解决IT中所有问题的解决方案。 现在炒作早已一去不复返了,但是XML仍然存在。 可靠的DSL代表数据,而灵活的DSL。
<library>
<author firstName="John" lastName="Doe" id="JDOE" />
<book title="The Story of Mr. Doe" author="JDOE" />
</library>
尽管它不是最易读或令人印象深刻的语言,但是每个人都可以修改XML文件中包含的数据。
11. UML –可视化建模
并非所有的DSL都必须是文本的! 语言也可以是图形的。 例如, 统一建模语言是一种规则明确的语言。 它可以用来定义通常用于支持讨论的图表。 有人还使用它们来生成代码,甚至定义整个应用程序(如果您对这种东西感兴趣,请查看“模型驱动的体系结构”)。
UML是一种广泛的语言(有人说said肿吗?)。 UML保护伞之后包含许多不同种类的图表。 他们都有共同点。
并非所有人都同意UML是DSL 。 虽然它绝对是一种语言,但有人会说它不是特定于领域的,而是通用的。 可以通过UML配置文件来添加域特定性。 我认为它是特定于建模的语言。 现在,这是一个案例,它说明了定义什么是DSL以及什么不是DSL的规则并不容易,主要是因为域是很难定义的术语。
12. VHDL –硬件设计
VHDL是用于定义电路的DSL。 从前,电子工程师习惯于设计复杂的系统,直接决定使用哪些门以及如何将它们连接在一起。 VHDL改变了所有这一切,提供了那些工程师可以用来定义其系统的更高层次的概念。
DFF : process(RST, CLK) is
begin
if RST = '1' then
Q <= '0';
elsif rising_edge(CLK) then
Q <= D;
end if;
end process DFF;
摘自Wikipedia的示例。
有一些工具可以处理这些定义,以得出实际的电路布局,并准备好进行打印。 Verilog是另一个类似于VHDL的DSL。
13. ANTLR –词法分析器和解析器定义
ANTLR带有自己的DSL,用于定义词法分析器和解析器语法。 这些是用于识别文本结构的指令。
例如,这是词法分析器语法的一小段:
// Identifiers
ID : [_]*[a-z][A-Za-z0-9_]* ;
// Literals
INTLIT : '0'|[1-9][0-9]* ;
DECLIT : '0'|[1-9][0-9]* '.' [0-9]+ ;
STRINGLIT : '"' ~["]* '"' ;
JavaCC,Lex,Yacc和Bison是相似的工具,并且都受到Backus-Naur格式的启发,它们的DSL略有不同。
14.制作系统
Make是一种语言,用于描述如何构建内容以及不同步骤之间的依赖关系。 例如,您可以定义如何生成可执行文件,并指定要执行的操作,您首先需要3个目标文件。 然后,您可以为每个目标文件定义如何从相应的源文件中获取它。
CC=gcc
CFLAGS=-I.
DEPS = some_header_file.h
OBJ_FILES = file1.o file2.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
myExecutable: $(OBJ_FILES)
gcc -o $@ $^ $(CFLAGS)
在此示例中,我们指定要创建程序myExecutable,我们将需要目标文件,一旦有了它们,我们将使用gcc将它们链接在一起。
我们还可以在文件顶部定义一些常量,因此如果需要,以后可以很容易地更改Makefile。
15. Latex –文档布局
乳胶在学院和出版行业中被大量使用,以产生美观的论文和书籍。
\documentclass[12pt]{article}
\usepackage{lingmacros}
\usepackage{tree-dvips}
\begin{document}
\section{Introduction}
Here it start my introduction
\subsection{Details}
Here I go in more details.
\end{document}
以这种格式描述文档后,通常会生成PDF。
这很不错,因为它可以处理对图形或表格的引用,他可以自动对它们进行编号,它使您可以以非常复杂的方式控制表格的布局。 如果您精通LaTeX,您将获得不错的结果。
16. OCL –模型约束
OCL代表对象约束语言,可用于定义对象的其他约束。 通常,它与UML一起使用。
例如,如果您有一个具有两个属性start和end的 Appointment类,则可能要指定约会的结束遵循其开始 :
context Meeting inv: self.end > self.start
您还可以为适用于类的操作或不变量定义前置条件和后置条件。
如果您对这种东西感兴趣,您可能还需要研究QVT ,这是一组用于定义模型转换的语言。
17. XPath – XML节点选择
XPath可用于选择XML文档中的节点。 例如,假设您有一个代表餐厅列表的文档,而您想获取最后一个餐厅:
/restaurants/restaurant[last()]
XPath表达式用于XSLT中,以定义要转换的元素,或者它们可以与许多库结合使用,以用于各种语言,以定义要从文档中提取的元素。 如果您想知道XSLT是什么,它是一种定义XML文档转换的语言。
18. BPEL –业务流程
BPEL是一种用于定义Web服务之间的协作以实现业务流程的语言。 当世界正经历其面向服务的体系结构 (SOA)阶段时,它曾经更加流行。
这种语言的目标是允许软件设计师甚至分析人员组合不同的Web服务或其他组件,以获得复杂的系统。
该语言有不同的实现方式,每种都具有扩展名,并且彼此之间大多不兼容。
19. Actulus建模语言–用于计算人寿保险和养老金的DSL
riskmodel RiskLifeDeath(p : Person) : LifeDeath(p) where
intensities =
alive -> dead by gompertzMakehamDeath(p)
此示例摘自David Christiansen等人的论文“人寿保险和养老金精算编程语言”。
此DSL在“ 金融领域专用语言列表”中列出 ,您可以在其中找到更多类似的示例。
那么我们可以将DSL用于什么呢?
查看这些示例后,我们可以得出DSL可用于多种目标的情况:
- 定义要执行的命令:如sed或gawk
- 描述文件或其某些特定方面:例如html,乳胶或CSS
- 定义规则或流程:例如BPMN或Actulus
这些只是一些典型用法,但是由于许多其他原因,可以使用DSL。
同样重要的是要注意,DSL专注于系统的一个特定方面,通常将其中的几个结合起来描述产品的不同方面是有意义的。 例如,HTML和CSS一起用于描述内容和样式或文档,XML和XPath用于定义数据以及如何遍历该数据。 OCL用于定义对UML模型的约束。
您可能会想到不设计一个DSL,而是设计一个家庭或相关的DSL。
好的,在这一点上,您应该对DSL的外观以及其用途有一些了解。 现在让我们看看为什么要使用一个,然后再构建一个。
DSL与GPLS:使用域特定语言的5个优点
您可能会问自己以下问题:
为什么使用特定的有限语言而不是通用的功能强大的语言?
简短的答案是领域特定语言在它们可以做的事情上受到限制,但是由于它们的专业化,它们可以在自己的有限领域中做更多的事情。
让我们具体说一下,看看五个独立的优点:
- 我们可以对它们进行更好的分析:尽管实际上不可能保证用C或Java编写的程序会尊重某些特征(例如不以无限循环结尾),但是当我们使用DSL时,我们可以执行各种分析。 正是由于它们的功能有限,它们更易于分析。
- 他们更安全。 使用DSL时,可能出错的事情更少。 使用HTML或SQL时最后一次出现Null指针异常是什么时候? 没错 如果我们正在做一些重要的事情,例如处理某人或他的钱的健康,这一点非常重要。
- 当存在错误时,这些错误是特定于域的错误,因此更易于理解。 它们是特定于域的:因此错误与空指针无关,而与域专家可以理解的事情有关。
- 这也意味着解释更容易,因此将它们引入新平台也很容易。 模拟器也是如此。 我们可以在2000年在PDA上打开HTML文档现在可以在iPad pro上打开。
- 我们可以更轻松地教授它们:它们的范围有限,因此仅需学习较少的内容即可掌握它们所需的时间和培训更少。