`
txf2004
  • 浏览: 7041869 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Groovy探索 DSL在Calendar类上的实践 一

阅读更多

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

}

}

分享到:
评论

相关推荐

    java开源包7

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包1

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    JAVA上百实例源码以及开源项目源代码

    Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个...

    java开源包11

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包2

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包3

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包6

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包5

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包10

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包4

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包8

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包9

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java开源包101

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    Java资源包01

    DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列...

    java8-dropwizard-gradle:带有Gradle的最小Java8 + Dropwizard项目

    1. **Groovy DSL**:使用Groovy语言编写构建脚本,语法更加自然和灵活。 2. **依赖管理**:自动解决项目依赖,并可以从Maven或Ivy仓库下载。 3. **插件生态系统**:丰富的插件库,支持各种任务和集成。 4. **增量...

Global site tag (gtag.js) - Google Analytics