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,getDate()+howlong) ?????? } ?????? this ??? } ??? ??? def set(map) ??? { ?????? if(map.year) ?????? { ?????????? cal.set(Calendar.YEAR,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 ? ? } ? } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |