DSL——基础知识
外部DSL是一门需要编译或者解释运行的编程语言,而内部DSL则构建于一门通用编程语言(general-purpose programming language)之内。实际上,内部DSL对于其宿主通用编程语言来说,就是它的一套层次非常高的API。Martin Flower的原文描述。
当然,并非我们关注的领域都有现成的DSL,这时候我们有三个选择:
- 使用通用语言描述该领域的问题(non-DSL)
- 发明一门全新的语言描述该领域的问题(External DSL)
- 在一门现成语言内实现针对领域问题的描述(Internal DSL)
I.DepositTo(new USD(200), CitiBank); /* C# */
I deposit 200USD to CitiBank /* E-DSL */
I.deposit(200.USD()).to(CitiBank); /* I-DSL */
deposit [something] to [somewhere]
?)。 第2种做法的成本最高,你需要写一个全新的解释器,至少是写一组全新的规则,然后让YACC这类工具帮你生成一个解释器,但这样出来的语法最贴近人类思维方式,甚至就如同自然语言一样流畅。
第3种做法术语上述两者的折中方案,如果语法不太复杂可以使用Builder模式实现语法分析,写出来的语法相当贴近自然语言,但还是有学习门槛。由于脚本语言有相当的灵活性,所以现在很多人倾向于选择在脚本语言内实现Internal DSL。
如何构造Internal DSL?
常见的两种Internal DSL实现方法是Method Chaining和Function Sequence。
不错的实例:
基于DSL的Lambda Code