dsl口是什么意思啊 dsl是什么意思啊

最近在一个项目中,因为涉及很多状态的流转,我们选择使用状态机引擎来表达状态流转 。因为状态机DSL(Domain Specific Languages)带来的表达能力,相比较于if-else的代码,要更优雅更容易理解 。另一方面,状态机很简单,不像流程引擎那么华而不实 。
一开始我们选用了一个开源的状态机引擎,但我觉得不好用,就自己写了一个能满足我们要求的简洁版状态机,这样比较KISS(Keep It Simple and Stupid) 。
作为COLA开源的一部分,我已经将该状态机(cola-statemachine)开源,你可以访问https://github.com/alibaba/COLA获取 。
【dsl口是什么意思啊 dsl是什么意思啊】在实现状态机的过程中,有幸看到Martin Fowler写的《Domain Specific Languages》 。书中的内容让我对DSL有了不一样的认知 。
这也是为什么会有这边文章的原因,希望你看完这边文章以后,可以对什么是DSL、如何使用DSL、如何使用状态机都能有一个不一样的体会 。
DSL在介绍如何实现状态机之前,不妨让我们先来看一下什么是DSL,在Martin Fowler的《Domain Specific Languages》书中 。开篇就是以State Machine来作为引子介绍DSL的 。有时间的话,强烈建议你去读读这本书 。没时间的话,看看下面的内容也能掌握个大概了 。
下面就让我提炼一下书中的内容,带大家深入了解下DSL 。
什么是DSLDSL是一种工具,它的核心价值在于,它提供了一种手段,可以更加清晰地就系统某部分的意图进行沟通 。
这种清晰并非只是审美追求 。一段代码越容易看懂,就越容易发现错误,也就越容易对系统进行修改 。因此,我们鼓励变量名要有意义,文档要写清楚,代码结构要写清晰 。基于同样的理由,我们应该也鼓励采用DSL 。
按照定义来说,DSL是针对某一特定领域,具有受限表达性的一种计算机程序设计语言 。这一定义包含3个关键元素:

  • 语言性(language nature):DSL是一种程序设计语言,因此它必须具备连贯的表达能力——不管是一个表达式还是多个表达式组合在一起 。
  • 受限的表达性(limited expressiveness):通用程序设计语言提供广泛的能力:支持各种数据、控制,以及抽象结构 。这些能力很有用,但也会让语言难于学习和使用 。DSL只支持特定领域所需要特性的最小集 。使用DSL,无法构建一个完整的系统,相反,却可以解决系统某一方面的问题 。
  • 针对领域(domain focus):只有在一个明确的小领域下,这种能力有限的语言才会有用 。这个领域才使得这种语言值得使用 。
比如正则表达式, /\d{3}-\d{3}-\d{4}/就是一个典型的DSL,解决的是字符串匹配这个特定领域的问题 。
DSL的分类按照类型,DSL可以分为三类:内部DSL(Internal DSL)、外部DSL(External DSL)、以及语言工作台(Language Workbench) 。
  • Internal DSL是一种通用语言的特定用法 。用内部DSL写成的脚本是一段合法的程序,但是它具有特定的风格,而且只用到了语言的一部分特性,用于处理整个系统一个小方面的问题 。用这种DSL写出的程序有一种自定义语言的风格,与其所使用的宿主语言有所区别 。例如我们的状态机就是Internal DSL,它不支持脚本配置,使用的时候还是Java语言,但并不妨碍它也是DSL 。
builder.externalTransition().from(States.STATE1).to(States.STATE2).on(Events.EVENT1).when(checkCondition()).perform(doAction());
  • External DSL是一种“不同于应用系统主要使用语言”的语言 。外部DSL通常采用自定义语法,不过选择其他语言的语法也很常见(XML就是一个常见选 择) 。比如像Struts和Hibernate这样的系统所使用的XML配置文件 。
  • Workbench是一个专用的IDE,简单点说,工作台是DSL的产品化和可视化形态 。
三个类别DSL从前往后是有一种递进关系,Internal DSL最简单,实现成本也低,但是不支持“外部配置” 。Workbench不仅实现了配置化,还实现了可视化,但是实现成本也最高 。他们的关系如下图所示:
dsl口是什么意思啊 dsl是什么意思啊

文章插图
dsl口是什么意思啊 dsl是什么意思啊

文章插图
dsl口是什么意思啊 dsl是什么意思啊

文章插图
dsl口是什么意思啊 dsl是什么意思啊

文章插图
Note:这里之所以叫Semantic Model,用的是《DSL》书里的术语,你也可以理解为是状态机的领域模型 。Martin用Semantic这个词,是想说,外部的DSL script代表语法(Syntax),里面的model代表语义(Semantic),我觉得这个隐喻还是很恰当的 。
OK,状态机语义模型的核心代码如下所示:
//StateMachinepublic class StateMachineImpl

    推荐阅读