Groovy探索 DSL在Calendar类上的实践 一
作为一个使用者,我不喜欢Java平台的Calendar类;同样,我也不喜欢Groovy平台的Calendar类。都是基于同样的原因,使用起来非常不方便。
同时,Groovy语言的DSL极大的吸引了我。使得我每每在使用Calendar类的时候,都会想到我可否使用DSL来改造这个Calendar类呢,权当一次使用DSL的实验。
在这样的想法下,我写了一点的DSL代码,用来检验我对于DSL的理解,同时,也想抛砖引玉,引来大家对于使用DSL来改造Calendar类的一些想法。
首先,我不喜欢使用如下的代码来获取单独的年、月、日的数据:
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.YEAR));
我喜欢形如"c.year"这样的代码来获取单独的年、月、日的数据。这种想法很简单,实现起来也不难,不就是给Calendar类多加几个"get"方法嘛。
我构造起我自己的Calendar类来,如下所示:
class MyCalendar {
def cal
def type
def MyCalendar()
{
cal = Calendar.instance
}
def getDate()
{
cal.get(Calendar.DATE)
}
def getMonth()
{
cal.get(Calendar.MONTH)+1
}
def getYear()
{
cal.get(Calendar.YEAR)
}
}
一切都很简单,现在,我们来测试一下吧:
def c = new MyCalendar()
println c.year+'/'+c.month+'/'+c.date
运行结果为:
2009/3/16
真的还蛮顺利的。
接着,我也不喜欢Calendar类的"set"方法,它的形式是这样的:
c.set(Calendar.YEAR, 2010);
如果我既想设定年份,还想设定月份,那么必须这么写:
c.set(Calendar.YEAR, 2010);
c.set(Calendar.MONTH, 3);
我喜欢这样的形式:
c.set(year:2010)
这也很简单啊,不就是一个Map参数的方法嘛,于是,我在MyCalendar类里继续加入了如下的方法:
def set(map)
{
if(map.year)
{
cal.set(Calendar.YEAR,map.year)
}
if(map.month)
{
cal.set(Calendar.MONTH,map.month)
}
if(map.date)
{
cal.set(Calendar.DATE,map.date)
}
}
现在,我们就可以写代码来测试一下了:
def c = new MyCalendar()
c.set(year:2010)
println c.year+'/'+c.month+'/'+c.date
运行的结果为:
2010/3/16
当然了,如果我们既想设定年份,又想设定月份,代码就是形如下面的形式:
c.set(year:2010,month:4)
对于年份的运算,比如当前年份加上3年,我就更不喜欢下面的形式了:
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, c.get(Calendar.YEAR)+3);
System.out.println(c.get(Calendar.YEAR));
我喜欢下面的形式:
c = c+3.year
要达到上述的目的,我们首先要在MyCalendar类里重载"plus"方法,使得MyCalendar类能够和数字相加。
def plus(howlong)
{
if(type==1)
{
cal.set(Calendar.YEAR,getYear()+howlong)
}
else if(type==2)
{
cal.set(Calendar.MONTH,getMonth()+howlong)
}
else if(type==3)
{
cal.set(Calendar.DATE,getDate()+howlong)
}
this
}
首先判定相加的数字是年份、月份还是日期,然后再使用Calendar类的加法。
接着,光重载"plus"方法还不够,我们需要识别形如"3.year"这样的表达式。在这里,Groovy语言的MOP能帮得上忙。
def mc = new ExpandoMetaClass(Integer.class,true)
mc.getDate <<
{
->
c.type = 3
delegate
}
mc.getMonth <<
{
->
c.type = 2
delegate
}
mc.getYear <<
{
->
c.type = 3
delegate
}
mc.initialize()
当所有这一切完成之后,我们就可以来测试了:
c = c+3.date
println c.year+'/'+c.month+'/'+c.date
c = c+2.month
println c.year+'/'+c.month+'/'+c.date
运行结果为:
2010/5/19
2010/8/19
最后,我把整个的Calendar类的代码附上。
class MyCalendar {
def cal
def type
def MyCalendar()
{
cal = Calendar.instance
}
def getDate()
{
cal.get(Calendar.DATE)
}
def getMonth()
{
cal.get(Calendar.MONTH)+1
}
def getYear()
{
cal.get(Calendar.YEAR)
}
def plus(howlong)
{
if(type==1)
{
cal.set(Calendar.YEAR,getYear()+howlong)
}
else if(type==2)
{
cal.set(Calendar.MONTH,getMonth()+howlong)
}
else if(type==3)
{
cal.set(Calendar.DATE,getDate()+howlong)
}
this
}
def set(map)
{
if(map.year)
{
cal.set(Calendar.YEAR,map.year)
}
if(map.month)
{
cal.set(Calendar.MONTH,map.month)
}
if(map.date)
{
cal.set(Calendar.DATE,map.date)
}
}
static void main(args) {
def c = new MyCalendar()
println c.year+'/'+c.month+'/'+c.date
c.set(year:2010,month:4)
println c.year+'/'+c.month+'/'+c.date
def mc = new ExpandoMetaClass(Integer.class,true)
mc.getDate <<
{
->
c.type = 3
delegate
}
mc.getMonth <<
{
->
c.type = 2
delegate
}
mc.getYear <<
{
->
c.type = 3
delegate
}
mc.initialize()
c = c+3.date
println c.year+'/'+c.month+'/'+c.date
c = c+2.month
println c.year+'/'+c.month+'/'+c.date
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hivon/archive/2009/03/19/4003165.aspx
分享到:
相关推荐
Groovy has been a trendsetter for this development. Many Groovy features that ease the burden of developers are now commonplace in novel languages and may even find their way into newer versions of ...
使用此集成,您可以快速将 SSH 服务器添加到您的应用程序,并能够远程访问 Groovy shell,让您在正在运行的 JVM 中以交互方式运行代码。 换句话说,它是一个可远程访问的 REPL,位于您的 JVM 中,从而允许您检查...
01-date-server-simple文件夹包含简单但功能齐全的Groovy脚本,该脚本运行Ratpack应用程序,该应用程序使用当前日期字符串响应HTTP GET请求。 要运行该示例,只需在01-date-server-simple目录中键入以下命令: ...
在“插件”部分中将其添加到您的BuildConfig.groovy中。 compile ":java8-temporal:0.2" 数据绑定 该插件增加了对以下类型的绑定支持: 年 年月 当地时间 本地日期 LocalDateTime 立即的 ZonedDateTime JSON和...
Summary Gradle in Action is a comprehensive guide to end-to-end project automation with Gradle. Starting with the basics, this ...Publication Date: 2014-03-09 ISBN-10: 1617291307 ISBN-13: 9781617291302
主要介绍了JAVA 获取系统当前时间实例代码的相关资料,需要的朋友可以参考下
Tox21浓缩机 Tox21 Enricher是一个仍在开发中的Web应用程序。 它对Tox21集合中包含的一种或多种化学物质进行PubChem富集分析,并将其与NIEHS合作...Tox21 Enricher开发中使用的工具: Groovy(2.5.6) 谷物(4.0.2)
为什么要使用XML,Groovy,Scala,JavaScript或其他某种语言来构建项目? 这是供跨平台使用的,特别是-linux 32/64,mac 32/64和Windows 32/64。 Java 6+ 能够复制与远程构建完全相同的构建(提供相同的“ build...
The most up-to-date comprehensive guide to use Grails for rapid web development. 最新最全版本使用Grails进行快速web应用程序开发。英文版。原汁原味,通俗易懂。由Grails项目组组长亲自编写,涉及Grails的每...
Seam - 语境相关的组件[满江红20071230]............................................................................................................................ 1 Java EE 框架...........................
6.9.1 Java中的Date类 94 6.9.2 Java中的GregorianCalendar类 96 6.9.3 擅用系统已有类的思想 98 6.10 小结 99 第7章 访问控制——Java世界的卫兵 100 7.1 包的使用 100 7.1.1 声明创建包 100 7.1.2...
3.5. Groovy Bean Definition DSL .............................................................................. 18 3.6. Core Container Improvements ........................................................
3.5. Groovy Bean Definition DSL .............................................................................. 18 3.6. Core Container Improvements ........................................................