天天看点

Groovy探索之闭包 一

                                        Groovy探索之闭包 一   动态语言的闭包是一个永恒的话题。闭包在编码过程的方便和快捷使得动态语言的拥护者对它津津乐道,而静态语言特别是Java语言的扇子们会拿出匿名内部类来说Java语言也有类似的功能。我使用Java语言至今也有六七年的时间了,实话来说我也很喜欢Java语言,但我万万不敢拿Java语言的匿名内部类和闭包来对比。因为匿名内部类的隐晦和繁琐,使得我在编码的过程中很少使用它,怎么敢拿它出来吹嘘呢?而在我使用Groovy编码的不到一年的过程中,我却时时刻刻在使用闭包。 闭包实在是太方便和灵活了,使得我在使用它的时候信手拈来。在我看来,闭包就像Groovy等动态语言给我们的一道鱼翅大餐。这道大餐的好处需要我们慢慢的一一道来,记得星爷的《济公》里有一句台词:来碗鱼翅嗽嗽口。不错,今天我们先要说说闭包在Groovy编码过程中随处可用小用法,权当使用闭包这碗鱼翅来嗽嗽口。 温馨提示,阅读本文需要您有闭包的基础知识。例如,关于闭包的定义及调用;闭包的参数、变量和返回值的作用域等一些简单的基础知识。当然,您也可以试着在阅读本文的时候,同时把上述的基础知识一并找来看,借此来相互理解和相互支持。对闭包基础阐述得最清楚的书籍是《Groovy in Action》 一.小试身手,随处可用 Java语言的编码过程中,有随处可见的我们用起来觉得别扭的地方,却又无计可施。例如,我们经常要对一系列的String进行非空判断以后再进行操作: if(str1!=null&&!str1.trim().equals(“”)) {         …… } if(str2!=null&&!str2.trim().equals(“”)) {         …… } if(str3!=null&&!str3.trim().equals(“”)) {         …… } …… 这样反复的if判断真让人忍无可忍,但是你没有好的解决办法,只能这样五个、六个甚至十个的写下去。 Stop!我们来考虑一下闭包的解决方案吧。 来,我们先定义一个闭包,很简单。 def isNotNull = {         str,Closure closure ->               if (str!= null &&!str.trim().equals( "" ))               {                  closure. call ()               }  } 很普通的 一个闭包,两个输入参数,如果没明白的话,现在就翻出闭包的基础知识看一看。 简单的闭包定义好了以后,我们就可以开始使用它了: def abc = 'abc'      isNotNull(abc)      {          println abc  } 在上面的例子中,我们小试牛刀了一次,只是判断了一下字符串 abc 是否为空,如果不为空就打印到控制台。比起我们上面的 if 语言,是不是简洁多了。 像这样的用法,我们在编码的过程中随处可见,下面再举一个例子:        String cateType = getRequest().getParameter( "cateType" ); //1: 确认存储 2:反确认        String cateId = getRequest().getParameter( "cateId" );        String year = getRequest().getParameter( "year" );     String percent = getRequest().getParameter( "percent" ); 不错,这是一段获取 request 参数的代码。我们在写这样的代码的时候,多了就会郁闷,我老是先要 getRequest , 然后 getParameter , 重复的同样的锻炼我们的盲打能力。 Stop !我们来使用闭包减轻我们的打字频率吧。 同样,先是定义一个闭包:       def getReqParam = {             paramName ->               return getRequest().getParameter(paramName)  } 那么,上面的代码,我们可以写成下面的样子: String cateType = getReqParam( "cateType" ); //1: 确认存储 2:反确认        String cateId = getReqParam( "cateId" );        String year = getReqParam( "year" );     String percent = getReqParam( "percent" ); 怎么样 , 是不是简洁多了?   二.神来之笔 除了上面的一些小用法,闭包的灵活性在编码的过程中随时可能显示出来。你会在Java编程过程中随时找到一些对闭包的妙用。 比如,我们在编码的过程中,随时会做一些log记录。     logger .debug( "importPartList condition:" ); logger .debug( "userid=" + excelModel.getUserid()); 这样的 log 是我们常用的,但鉴于性能方面的要求,我们实际上不会直接打印 log ,而是首先判断 log 的开关状态。如下:        if ( logger .isDebugEnabled()) {            logger .debug( "isPPRMBuyer=" + isPPRMBuyer);     } 下面的一小段代码就是这样一个场景。        if ( logger .isDebugEnabled()){            logger .debug( "updateAfterUploadRaw start:" );        }               ret = (String)dao.getObjectByStoredProcedure(               "updateBuyerCRDetail" ,               map,               new String[]{ "v_matetype" },               OracleTypes. VARCHAR );        if ( logger .isDebugEnabled()){            logger .debug( "1. updateBuyerCRDetail result ret=" + ret);        }             if (!ret.equals( "0" ))        {            errMsg += "Update Buyer 管控總表 failed! " ;        }               ret = (String)dao.getObjectByStoredProcedure(               "updateBuyerCRDetailYt" ,               map,               new String[]{ "v_matetype" },               OracleTypes. VARCHAR );               if ( logger .isDebugEnabled()){            logger .debug( "2. updateBuyerCRDetailYt result ret=" + ret);     } 可以看到,就是上面的一小段代码,却已经使用了三个 if ( logger .isDebugEnabled()) 。 这样重复使用的判断语句让我们在编码的过程中相当郁闷,可能有很多人想把它抽象成下面的一个方法:     public static void debug(logger,String str)     {        if (logger.isDebugEnabled())         {            logger.debug(str);        } } 这样使用使用固然是方便了很多,但却违背了我们使用该判断语句的初衷,即不能解决性能方面的问题。 显然,这不是一个好的解决方法。 现在,我们来看看闭包的解决方法:       def isdebuged = {             Closure closure ->               if (logger.isDebugEnabled())              {                   closure. call ();              }  } 使用这个闭包,上面的那一小段代码就变成下面的样子:        isdebuged {            logger .debug( "updateAfterUploadRaw start:" );        }               ret = (String)dao.getObjectByStoredProcedure(               "updateBuyerCRDetail" ,               map,               new String[]{ "v_matetype" },               OracleTypes. VARCHAR );        isdebuged {            logger .debug( "1. updateBuyerCRDetail result ret=" + ret);        }             if (!ret.equals( "0" ))        {            errMsg += "Update Buyer 管控總表 failed! " ;        }               ret = (String)dao.getObjectByStoredProcedure(               "updateBuyerCRDetailYt" ,               map,               new String[]{ "v_matetype" },               OracleTypes. VARCHAR );               isdebuged {            logger .debug( "2. updateBuyerCRDetailYt result ret=" + ret);     } 这样,我们就可以从写 if判断语句中解脱出来。 好了,作为系列《Groovy探索之闭包》的第一篇,我们暂时谈到这里。上面的例子可能有人觉得毫无意义,没有太大的用处,但是我举出这些例子是为了提供一些使用闭包的思路,并不见得实际编码过程中就要这样用。 闭包还有很多有趣的、方便快捷的使用方法。我们会在后续的文字中一一道来。