一: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 "</${name}>"
} html {
head {
meta { }
}
body {
table (style:'margin:5px;') {
tr ('class':'trClass', style:'padding:5px;') {
td {'Cell1'}
td {'Cell2'}
td {'Cell3'}
}
}
}
}

六:运行结果

<html><head><meta></meta>
</head>
<body><table style ='margin:5px;' >
<tr class ='trClass' style ='padding:5px;' >
<td>Cell1</td>
<td>Cell2</td>
<td>Cell3</td>
</tr>
</table>
</body>
</html>

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

Groovy 与 DSL的更多相关文章

  1. 第一篇:groovy对DSL的语法支持

    引子 我们用一段gradle的脚本做引子,理解这一段脚本与一般的groovy代码是怎么联系起来的 buildscript { repositories { jcenter() mavenLocal() ...

  2. 使用Groovy构建DSL

    DSL(Domain Specific Language)是针对某一领域,具有受限表达性的一种计算机程序设计语言. 常用于聚焦指定的领域或问题,这就要求 DSL 具备强大的表现力,同时在使用起来要简单 ...

  3. 走进Groovy (一)

    一直很喜欢脚本语言,但是一直在不大的公司工作,用得一直是“高大上”的JAVA语言,在真正的项目中,没什么机会用到脚本语言.这两年,又断断续续的用了2年的Ruby,再回头继续用JAVA,说实话,真感觉J ...

  4. 即时编译和打包您的 Groovy 脚本(转)

    在本文中将会涉及到: 使用 CliBuilder 来实现对命令行选项的支持,脚本执行时所需要的参数将通过命令行选项的方式传递. 使用 GroovyClassLoader 加载 Groovy class ...

  5. Groovy实现原理分析——准备工作

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  6. 如何在Maven和Gradle中配置使用Groovy 2.4与Spock 1.0

    如何在Maven和Gradle中配置使用Groovy 2.4与Spock 1.0 原文 https://dzone.com/articles/spock-10-groovy-24 翻译 hxfiref ...

  7. Groovy语法基础

    Groovy 简介 Groovy 是一种基于 JVM 的动态语言,他的语法和 Java 相似,最终也是要编译 .class 在JVM上运行. Groovy 完全兼容 Java 并且在此基础上添加了很多 ...

  8. 【Bugly 技术干货】Android开发必备知识:为什么说Kotlin值得一试

    1.Hello, Kotlin Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 1. ...

  9. fir.im Weekly - 给 Mac 应用开发者的教程

    写作是一件苦差事.无论写代码,还是写文章. 关于 Mac 应用开发,国内很少有完整的书籍或教程.最近@剑指人心写的 <Mac 应用开发基础教程>终于!完!稿!了! 这本书中对 Mac 平台 ...

随机推荐

  1. P4551 最长异或路径

    题目描述 给定一棵 nnn 个点的带权树,结点下标从 111 开始到 NNN .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式 ...

  2. 已知UIScrollView放大后的Frame和放大之前的Frame计算放大的瞄点坐标

    有时候在缩放后,需要知道该次缩放是在哪个坐标开始缩放的.如上篇已知缩放的点,然后在该点对其缩放.本篇其实是逆运算 (x,y)就是当初在该点进行缩放 化简之后很简单,代码如下: func getZoom ...

  3. BZOJ3771 Triple 【NTT + 容斥】

    题目链接 BZOJ3771 题解 做水题放松一下 先构造\(A_i\)为\(x\)指数的生成函数\(A(x)\) 再构造\(2A_i\)为指数的生成函数\(B(x)\) 再构造\(3A_i\)为指数的 ...

  4. 弄清楚CSS的匹配原理让你写出高效的CSS

    用了这么多年的CSS,现在才明白CSS的真正匹配原理,不知道你是否也跟我一样?看1个简单的CSS: DIV#divBox p span.red{color:red;} 按习惯我们对这个CSS 的理解是 ...

  5. C++中添加配置文件读写方法

    比如有一个工程,一些变量有可能需要不时的修改,这时候可以通过从配置文件中读取该数值,需要修改时只需要修改配位文件即可. 比如有一个这样的变量m_nTest; 我么可以写两个函数ReadConfig() ...

  6. linux根据进程pid查看进程详细信息

    http://note.youdao.com/noteshare?id=af2fdd34e3adfacda2d34706e16e5045

  7. 手脱PEncrypt 4.0

    1.载入PEID PEncrypt 4.0 Gamma / 4.0 Phi -> junkcode [Overlay] 2.载入OD,没什么头绪,忽略所有异常,用最后一次异常法shift+F9运 ...

  8. 云巴-JavaScript API测试与实例(新)

    一.云巴介绍 给大家推荐一个提供后台消息服务的服务供应商,个人用户一般是免费的,可作为开发者的后台服务提供商. 官网 专注于为需要实时数据交换的产品提供完美解决方案.支持包括 手机.Web.智能设备 ...

  9. sql分页demo

    ALTER proc [dbo].[ProcGetUserInfoPageInfoByUserName] ), @PageIndex int, @PageSize int as Begin selec ...

  10. 庞老师集群.ziw

    2017年2月17日, 星期五 庞老师集群 链接:http://pan.baidu.com/s/1mhSw2TE 密码:hzz4   更改子网IP,及网关:     null