<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    First they ignore you
    then they ridicule you
    then they fight you
    then you win
        -- Mahatma Gandhi
    Chinese => English     英文 => 中文             
    隨筆-221  評論-1047  文章-0  trackbacks-0
    利用Groovy與生俱來的動態(tài)特性,創(chuàng)建DSL(Domain Specific Language)是一件十分容易的事情。
    下面通過一個例子,向大家展示一下用Groovy創(chuàng)建DSL的優(yōu)雅之處:

    利用下面這種語法
    ??? person {
    ??????? name {
    ??????????? firstname 'Daniel'
    ??????????? lastname? 'Sun'
    ??????? }
    ??? }

    ??? person {
    ??????? name {
    ??????????? firstname = '山風(fēng)'
    ??????????? lastname? = '小子'
    ??????? }
    ??? }
    創(chuàng)建一個Person對象。

    def?createMetaClass(Class?clazz,?Closure?closure)?{
    ????
    /*?
    ????????為傳入的Class對象創(chuàng)建一個ExpandoMetaClass實例,但不將該ExpandoMetaClass實例注冊到MetaClassRegistry對象中
    ????
    */
    ????def?emc?
    =?new?ExpandoMetaClass(clazz,?false)?
    ????
    /*
    ????????該closure用來初始化ExpandoMetaClass對象,這種寫法的思想與Template?Method?Pattern有異曲同工之妙
    ????
    */
    ????closure(emc)?
    ????emc.initialize()?
    //?完成初始化過程
    ????return?emc
    }

    def?executeScript(dslScriptCode,?rootName,?closure)?{
    ????Script?dslScript?
    =?new?GroovyShell().parse(dslScriptCode)??//?讀取并解析DSL代碼,返回一個Script對象
    ????
    ????dslScript.metaClass?
    =?createMetaClass(dslScript.class)?{?emc?->
    ????
    /*
    ????????動態(tài)新增一個名為"$rootName"的方法,注意"$rootName"的值決定于運行時,比如本例中的值為person
    ????
    */
    ????????emc.
    "$rootName"?=?closure?
    ????}
    ????
    ????
    return?dslScript.run()?//?執(zhí)行DSL代碼
    }

    class?Name?{
    ????String?firstname
    ????String?lastname
    ????String?toString()?{
    ????????
    "$firstname.$lastname"
    ????}
    }

    class?Person?{
    ????Name?name
    ????Person(name)?{
    ????????
    this.name?=?name
    ????}
    ????String?toString()?{
    ????????
    "My?name?is?$name"
    ????}
    }

    /*
    PersonDelegate對象是下面作為參數(shù)傳入‘person方法’的closure的delegate,形象點說,closure就是那對大括號{}以及大括號中的內(nèi)容
    如果您對closure的delegate不太熟悉,可以參考在下的另一篇文章《Groovy解惑——closure中的delegate》(
    http://www.tkk7.com/BlueSUN/archive/2007/12/22/169580.html)
    ????person?{
    ????????
    ????}
    */
    class?PersonDelegate?{
    ????def?person
    ????PersonDelegate(person)?{
    ????????
    this.person?=?person
    ????}
    ????
    /*?
    ????????關(guān)于methodMissing這一特殊方法,請參考在下的另一篇文章《Groovy高效編程——動態(tài)改變對象的能力》(
    http://www.tkk7.com/BlueSUN/archive/2007/07/15/130318.html)
    ????
    */
    ????def?methodMissing(String?name,?Object?args)?{
    ????????
    if?('name'?==?name?&&?args[0]?instanceof?Closure)?{
    ????????????def?nameClosure?
    =?args[0]
    ????????????
    /*?
    ????????????????給nameClosure的delegate賦值,nameClosure就是name旁邊的那個closure即一對大括號{}以及大括號中的內(nèi)容
    ????????????
    */
    ????????????nameClosure.delegate?
    =?new?NameDelegate(person)??
    ????????????nameClosure.resolveStrategy?
    =?Closure.DELEGATE_FIRST?//?指明closure中變量和方法的解析策略,本例選擇DELEGATE_FIRST
    ????????????nameClosure()
    ????????}
    ????}
    ????
    /*?
    ????????關(guān)于propertyMissing這一特殊方法,請參考在下的另一篇文章《Groovy高效編程——動態(tài)改變對象的能力》(
    http://www.tkk7.com/BlueSUN/archive/2007/07/15/130318.html)
    ????
    */
    ????def?propertyMissing(String?name)?{}
    }

    /*
    類似于PersonDelegate,
    NameDelegate對象是下面作為參數(shù)傳入‘name方法’的closure的delegate
    ????????name?{
    ????????????
    ????????}
    */
    class?NameDelegate?{
    ????def?person
    ????NameDelegate(person)?{
    ????????
    this.person?=?person
    ????}
    /*
    ????下面這些getter和setter是為了實現(xiàn)下面這種賦值而寫的:?firstname?=?'山風(fēng)'和lastname??=?'小子'
    ????person?{
    ????????name?{
    ????????????firstname?=?'山風(fēng)'
    ????????????lastname??=?'小子'
    ????????}
    ????}
    */
    ????def?getFirstname()?{
    ????????
    return?person.name.firstname
    ????}
    ????def?setFirstname(String?firstname)?{
    ????????person.name.firstname?
    =?firstname
    ????}
    ????def?getLastname()?{
    ????????
    return?person.name.lastname
    ????}
    ????def?setLastname(String?lastname)?{
    ????????person.name.lastname?
    =?lastname
    ????}
    ????
    ????def?methodMissing(String?name,?Object?args)?{
    ????????
    if?('firstname'?==?name)?{
    ????????????person.name.firstname?
    =?args[0]
    ????????}?
    else?if?('lastname'?==?name)?{
    ????????????person.name.lastname?
    =?args[0]
    ????????}
    ????}
    ????def?propertyMissing(String?name)?{}
    }

    /*
    ????在這篇文章中,演示了兩種賦值方式,各位可以根據(jù)自己的喜好選擇一種,我個人偏好第一種?:)
    */

    //?本例DSL的第一種寫法
    def?dslScriptCode?=?'''
    ????person?{
    ????????name?{
    ????????????firstname?
    'Daniel'
    ????????????lastname??
    'Sun'
    ????????}
    ????}
    '''

    def?scriptClosure?
    =?{?Closure?personClosure?->
    ????def?person?
    =?new?Person(new?Name())
    ????personClosure.delegate?
    =?new?PersonDelegate(person)
    ????personClosure.resolveStrategy?
    =?Closure.DELEGATE_FIRST
    ????personClosure()
    ????
    ????
    return?person
    }
    def?person?
    =?executeScript(dslScriptCode,?'person',?scriptClosure)

    println?person


    //?本例DSL的第二種寫法
    def?dslScriptCode2?=?'''
    ????person?{
    ????????name?{
    ????????????firstname?
    =?'山風(fēng)'
    ????????????lastname??
    =?'小子'
    ????????}
    ????}
    '''

    def?scriptClosure2?
    =?{?Closure?personClosure?->
    ????def?person2?
    =?new?Person(new?Name())
    ????personClosure.delegate?
    =?new?PersonDelegate(person2)
    ????personClosure.resolveStrategy?
    =?Closure.DELEGATE_FIRST
    ????personClosure()
    ????
    ????
    return?person2
    }
    def?person2?
    =?executeScript(dslScriptCode2,?'person',?scriptClosure2)

    println?person2


    運行結(jié)果:
    My?name?is?Daniel.Sun
    My?name?is?山風(fēng).小子

    附:朝花夕拾——Groovy & Grails
    posted on 2008-05-17 00:38 山風(fēng)小子 閱讀(5703) 評論(1)  編輯  收藏 所屬分類: Groovy & Grails
    主站蜘蛛池模板: 亚洲精品中文字幕无乱码麻豆| 亚洲色欲久久久综合网东京热| 无码AV片在线观看免费| 美女免费精品高清毛片在线视| 亚洲理论在线观看| 日韩亚洲一区二区三区| 亚洲毛片不卡av在线播放一区| 可以免费看黄视频的网站| 一区二区三区福利视频免费观看| av网站免费线看| 免费人成在线观看播放a| 亚洲乱理伦片在线观看中字| 亚洲成人在线免费观看| 亚洲国产精品国自产电影| 在线a亚洲v天堂网2019无码| 四虎永久在线精品免费观看地址 | 最近免费中文在线视频| 中国在线观看免费的www| 全部在线播放免费毛片| 丰满亚洲大尺度无码无码专线 | 嫩草在线视频www免费看| 一级白嫩美女毛片免费| 成a人片亚洲日本久久| 亚洲高清乱码午夜电影网| 亚洲一级毛片在线观| 亚洲综合色区中文字幕| 亚洲AV无码专区在线亚| 亚洲午夜国产精品| 亚洲精品视频在线观看免费| 亚洲福利视频网址| 亚洲乱码无限2021芒果| 色在线亚洲视频www| 在线观看亚洲AV日韩AV| 亚洲日韩精品国产3区| 亚洲精品国产高清在线观看| 亚洲日韩中文字幕一区| 校园亚洲春色另类小说合集| 男男gay做爽爽的视频免费| 成人嫩草影院免费观看| 精品免费久久久久国产一区 | 国产成人亚洲综合色影视|