天天看點

Groovy探索之閉包 六

                                Groovy探索之閉包 六     探索閉包的應用是一件很有意思的事,它的有意思在于我們永遠不知道有哪些地方不能應用到閉包,或者說在每一個角落,你都能找到閉包讓人眼睛一亮的應用。今天到談到的是閉包的有關于DSL的應用。DSL應該是這兩年才興起的一個概念,有關它的一些知識,請查閱相關文檔。 DSL的優越性在于它的接近自然語言,以及它的編碼的友善和快捷。而閉包天生能夠展現DSL的這些優越性,是以,它被選做DSL的一種實作就不足為奇了。 下面試着舉出幾個例子來說說閉包在這方面的應用。 比如,有一個公司的人事管理有這樣的一些規定:員工每個月遲到3次會怎麼,早退三次會怎麼,請假三次又會怎麼,等等,等等。 在實作這樣的一個功能的時候,我們把員工的出勤記錄分為這樣的一些狀态:“O”代表按時出勤;“L”代表遲到;“H”代表請假;“E”代表早退。 我們有一個TimeLog的類為員工做出勤記錄:   class TimeLog {     String id     String name     String[] states }       假設一個員工的出勤記錄是這樣的:             def timelog = new TimeLog(id: '123' ,name: 'tom' )             def states = [ 'O' , 'L' , 'E' , 'O' , 'L' , 'H' , 'H' , 'H' ,                     'O' , 'O' , 'O' , 'O' , 'L' , 'L' , 'O' , 'O' ,                     'O' , 'O' , 'O' , 'O' , 'O' , 'O' , 'O' , 'O' ,                     'O' , 'O' , 'O' , 'O' , 'O' , 'O' ]            timelog.states = states     應用閉包,我們可以寫出如下的代碼來:             def IfThreeTimes = {         state,timeLog,Closure closure ->           int i = 0           for (tl in timeLog.states)          {               if (tl == state&&i == 3 )               {                  closure. call ()                  break               }               else if (tl == state )               {                  i++               }          }      }     閉包名為“IfThreeTimes”,意思是“如果三次了”,很好了解。它的參數有“state”,代表的是狀态,是什麼三次了,遲到還是請假。“timeLog”是某一個員工的出勤記錄。最後一個參數是一個閉包,“closure”指的是三次了以後要怎麼處理,可能的處理有:扣工資,沒有獎金,不能評優秀等等。 具體到如果我們要處理遲到的問題,我們可以使用curry方法再做一次抽象,代碼如下所示:         def IfThreeTimesLate = IfThreeTimes.curry( 'L' )     最後,我們來測試我們的 DSL :        IfThreeTimesLate(timelog){          println 'You will lose money'      }       結果為: You will lose money     做這樣的DSL編碼是不是很有意思。下面再來看一個例子。 公司有各種各樣的申請,如“請假申請”,“部門調動申請”,“求職申請”等等,這些申請都由相關人員進行準許或否決。 如請假申請類:   class Holiday {     String id     String name     String beginDate     String endDate     String reason     boolean approved }     下面還有一個求職申請類:   class Offer {     String name     String reason     boolean approved }     由上面的需求,我們可以建立如下的閉包:             def IfApproved = {             which,Closure closure ->               if (which.approved)              {                   closure. call ()              }      }     參數“which”是需要輸入哪一種申請;同樣,參數“closure”代表如果申請成功了的話,要做些什麼。             def holiday = new Holiday(id: '123' ,name: 'tom' ,approved: false )             def offer = new Offer(name: 'mike' ,approved: true )          IfApproved(holiday)      {          println 'You will have a holiday'      }            IfApproved(offer)      {          println 'good, your offer is approved'  }   運作結果為: good, your offer is approved     這個例子,除了使用到閉包,還使用到Groovy語言的動态特性,共同完成了這樣一個DSL的編寫。 上面的例子都很小,也很簡單,但是能夠幫助我們整理閉包在DSL方面的應用,我用來借以抛磚引玉,使得我們能夠在今後的應用中寫成更好的DSL來。

繼續閱讀