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
分享到:
相关推荐
这里,我们导入了Java的`java.util.Date`类,并使用Groovy的字符串插值特性打印出当前日期和时间。 Groovy也提供了许多内置的工具和库,如Gradle构建工具,它是用Groovy编写的,允许开发者以更简洁的方式编写构建...
Groovy是一种基于Java平台的动态编程语言,它与Java语法高度兼容,但提供了更简洁的语法和更强大的元编程能力。在"groovy代码-groovy 表达式练习"这个主题中,我们主要探讨Groovy中的表达式及其在实际编程中的应用。...
例如,如果你想使用Groovy的`Date`类,你可能需要导入`groovy.time.TimeCategory`,以便能够方便地处理日期和时间。导入后,你可以使用`use`关键字来激活类别,如`use(TimeCategory) { println date + 1.day }`。 ...
list = [1, 2, 'hello', new java.util.Date()] assert list.size() == 4 assert list.get(2) == 'hello' ``` - **注意**:在 Groovy 中,所有的数字都会被自动转换为对象。 **2. Map** - **定义与访问** - ...
在提供的文件列表中,“Groovy expression for default value of todays date.docx”可能包含了关于如何使用Groovy表达式来获取当前日期并设置为默认值的详细步骤或者示例代码。如果能够查看这个文档,将能提供更...
- `new Date()`创建当前时间的`Date`对象。 2. **日期时间格式转换** - 使用`SimpleDateFormat`类将日期转换为字符串或反之。 3. **日期加减运算** - 通过`Calendar`或`LocalDateTime`类进行日期加减操作。 4....
列表可以使用特殊的语法创建,如`[3, new Date(), 'Jan']`,并支持操作符重载,如`list + list == list * 2`。映射的创建同样简洁,如`[a: 1, b: 2]`,并可以直接通过键访问值,如`map['a']`和`map.b`。范围表达式如...
list = [1, 2, 'hello', new java.util.Date()] ``` - **特点**: - 列表中的元素可以是不同类型。 - 数字会被自动转换为对象。 - **访问元素**: ```groovy assert list.size() == 4 assert list.get(2) == ...
创建新记录时,可以定义一个新的对象并调用`save()`方法,如`def p = new Person(name:"Fred", age:40, lastVisit:new Date()); p.save()`。读取数据可以通过主键获取,如`def p = Person.get(1)`。更新和删除操作...
list = [1, 2, 'hello', new java.util.Date()] assert list.size() == 4 assert list.get(2) == 'hello' ``` - **注意**: 在 Groovy 中,一切皆为对象,这意味着即使是数字也会被自动转换为对象。 **1.2 Map**...
def text = 'The year is 2022 and the date is 12/31.' def numbers = text.findAll(/\d+/) println numbers // 输出:[2022, 12, 31] ``` 4. **`replace()`和`replaceAll()`方法** `replace()`方法用新字符...
使用此集成,您可以快速将 SSH 服务器添加到您的应用程序,并能够远程访问 Groovy shell,让您在正在运行的 JVM 中以交互方式运行代码。 换句话说,它是一个可远程访问的 REPL,位于您的 JVM 中,从而允许您检查...
Java Time API,自Java 8引入,为处理日期、时间和时区提供了强大的工具,显著优于之前的`java.util.Date`和`Calendar`类。本教程将深入探讨如何在Android中利用Java Time API(`java.time`包)来管理日期和时间。 ...
```groovy // 如果使用Jackson implementation 'com.fasterxml.jackson.core:jackson-core:2.9.4' implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.4' // 如果使用FastJson implementation '...
Date releaseDate Author author } ``` 默认情况下,类名会映射到小写且由下划线分隔的表名,而每个属性则映射到相应的列。 #### 四、GORM GORM (Grails Object Relational Mapping) 是 Grails 的 ORM 实现。它...
这个工具窗口允许用户方便地从数据库中提取和操作数据,而这里的重点在于两个特定的脚本:JSON-Camel-Groovy.json.groovy和IN-CONDITION.sql.groovy。 描述中提到"IDEA database tools and sql extractors",意味着...