博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Groovy 与 DSL
阅读量:4704 次
发布时间:2019-06-10

本文共 2013 字,大约阅读时间需要 6 分钟。

一:DSL 概念

指的是用于一个特定领域的语言(功能领域、业务领域)。在这个给出的概念中有 3个重点:

只用于一个特定领域,而非所有通用领域,比如 Java / C++就是用于通用领域,而不可被称为 DSL,同样也不可把 Groovy称为 DSL。

语言,必须经过编写后才可发挥它的功能。比如:五线谱编写后成乐谱; ANT编写用于编译; SVN命令编写后可对资源库进行操作; Shell编程; SQL编程; PL-SQL编程等等。

忽略具体的运行环境(媒介),可以是纸、 XML文件、命令行、 Shell、数据库等。

二:Groovy对 DSL的支持

Groovy不是 DSL,而是通用的编程语言。但 Groovy却对编写出一个全新的 DSL提供了良好的支持,这些支持都来自于 Groovy自身语法的特性,比如:

不需要 class定义,直接执行脚本

Groovy语法的简洁

Groovy提供了更多通俗易懂的方法

省略()和;等

等等

Groovy自身不是 DSL。 Groovy官方已经发布了较多基于 Groovy书写的 DSL,比如 GANT, GORM, XMLBuilder, HtmlBuilder等等。

三:我们的目标

实现一种使用 Groovy语法书写、用于构建 HTML的(其实就是 HtmlBuilder)的简单 DSL,如下:

html {      head {          meta {                        }      }      body {          table (style:'margin:5px;') {              tr ('class':'trClass', style:'padding:5px;') {                  td {
'Cell1'} td {
'Cell2'} td { 'Cell3'} } } } }

这段代码比较容易让人懂,很容易让人将 HTML与之对应起来。具体怎么实现能够通过这一段 DSL代码输出原始的 HTML呢?主要基于 Groovy的以下几个特性:

Groovy脚本,不用定义 class

Groovy的 invokeMethod方法

方法可不书写()

语句末尾省略;分号

不书写 return

四:代码分析

meta {  }  //这段代码的含义为:调用 meta方法,参数为一个闭包,闭包不执行任何代码。table (style:'margin:5px;') {  }  //这段代码的含义为:调用 table方法,第一个参数为 Map,第二个参数为闭包。tr ('class':'trClass', style:'padding:5px;') { td { 'Cell1'} td { 'Cell2'} td { 'Cell3'} } //这段代码的含义为: //调用 tr方法,第一个参数为 Map,第二个参数为闭包。 //闭包中,调用了 3 个 td方法,参数都为一个闭包;闭包中直接返回了一个字符串。

五:代码实现

将代码解读了以后,再结合 invokeMethod就很容易实现了,具体代码如下:

def invokeMethod(String name, args) {      print "<${name}"      args.each { arg ->          if (arg instanceof Map) { arg.each { print " ${it.key} ='${it.value}' " } } else if (arg instanceof Closure) { print '>' arg.delegate = this def value = arg.call() if (value) { print "${value}" } } } println "
" } html { head { meta { } } body { table (style:'margin:5px;') { tr ('class':'trClass', style:'padding:5px;') { td { 'Cell1'} td { 'Cell2'} td { 'Cell3'} } } } }

六:运行结果

Cell1 Cell2 Cell3

七:结论基于Groovy自身的语法简洁和众多特性,实现一个专属的DSL还是蛮简单的。

转载于:https://www.cnblogs.com/xingzc/p/6347673.html

你可能感兴趣的文章
Copy code from eclipse to word, save syntax.
查看>>
arguments.callee的作用及替换方案
查看>>
PHP echo 和 print 语句
查看>>
第一讲 一个简单的Qt程序分析
查看>>
Centos 6.5下的OPENJDK卸载和SUN的JDK安装、环境变量配置
查看>>
poj 1979 Red and Black(dfs)
查看>>
【.Net基础03】HttpWebRequest模拟浏览器登陆
查看>>
zTree async 动态参数处理
查看>>
Oracle学习之常见错误整理
查看>>
数据库插入数据乱码问题
查看>>
altium annotate 选项设置 complete existing packages
查看>>
【模式识别与机器学习】——SVM举例
查看>>
【转】IT名企面试:微软笔试题(1)
查看>>
IO流入门-第十章-DataInputStream_DataOutputStream
查看>>
DRF的分页
查看>>
Mysql 模糊匹配(字符串str中是否包含子字符串substr)
查看>>
python:open/文件操作
查看>>
流程控制 Day06
查看>>
Linux下安装Tomcat
查看>>
windows live writer 2012 0x80070643
查看>>