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

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

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

    posts - 176, comments - 240, trackbacks - 0, articles - 7

    關于代碼生成和DSL

    Posted on 2008-11-23 11:57 canonical 閱讀(1919) 評論(0)  編輯  收藏 所屬分類: 設計理論
        代碼生成(Code Generation)本身是一個非常宏大的概念。從某種意義上說,當我們明確了計算的意義之后,所做的一切都只是一系列代碼生成的過程,最終的目標是生成某種可執行的機器碼。對web程序員來說,代碼生成是最熟悉不過的了,每天我們所做的工作就是JSP=>Servlet=>HTML。不過,現在多數人腦海中的代碼生成,指的一般只是根據配置輸出一個或多個程序文本的過程,最常見的是根據數據庫模型生成增刪改查相關代碼。這種技術其實很少在小型以上的項目中起到積極的作用.因為一般的生成工具都沒有實現追加功能,無法適應模型的增量修改。此外一般生成的代碼相比于手工書寫的代碼要更加冗長,需要被直接理解的代碼總量不降反升.為圖一時之快,所要付出的是長期的維護成本。

       在應用開發中,有些領域是非常適合于使用代碼生成技術的。例如根據領域模型生成ORM(對象-關系映射)描述,或者根據接口描述生成遠程調用代理/存根 (Proxy/Stub)等。因為它們實際上只是對同一信息的不同技術形式或者不同技術層面的同義反復而已。這種生成最理想的方式是動態進行,可以隨時保持模型的有效性。RoR(RubyOnRails)框架中ActiveRecord技術便是一個成功的范例,它甚至提供了動態生成的DAO函數,減少了一系列的包裝調用過程。

       代碼生成更加深刻的應用是完成高層模型向低層模型的轉化,這一過程往往是非平凡(non-trivial)的。在Witrix平臺中通過代碼生成來支持領域抽象,可以用非常低的成本跨越結構障礙,將自定義的領域模型嵌入到現有的技術體系中。這其中我們的主要工作是解決了生成代碼與手工書寫代碼之間的有效隔離及動態融合問題,確保代碼生成可以反復的以增量的方式進行,同時支持最細粒度處對生成的代碼進行定制調整。

       舉一個簡單的例子,假設現在需要開發一個三步審批的流程,每一步的操作人可以錄入意見,可以選擇通過或者回退,可以選擇下一步操作的具體操作人,系統自動記錄操作時間,每個操作人可以查看自己的操作歷史等。雖然在現有技術體系中實現這一功能需要不少代碼,但是在業務層面上描述這一功能并不需要很多文字,實際需要提供的信息量很小。顯然,建立領域模型是比較適合的做法,可以定義一種DSL(Domain Specific Language)來描述這一模型。

       <flow_cp:SeqFlow>
         
    <step id="draft" userField="draferId" dateField="draftTime" waitStatus="drafted" />
         
    <step id="check" userField="checkerId" dateField="checkTime" opinionField="checkOpinion"
                       waitStatus
    ="sent" />
         
    <step id="approve" userField="approverId" dateField="approveTime"
                    opinionField
    ="approveOpinion" waitStatus="checked" passStatus="approved" />  
       
    </flow_cp:SeqFlow>

       以上功能涉及到多個操作場景,實現的時候需要補充大量具體信息,其中很大一部分信息來自于背景知識,例如顯示樣式,界面布局,前后臺通信方式等。以上模型可以進一步抽象為如下標簽
       <flow_cp:StepFlow3/>

      在不同應用中復用以上流程邏輯的時候可能需要局部修正,例如
       <flow_cp:StepFlow3>
          
    <step id="check" userField="checker" />
       
    </flow_cp:StepFlow3>

       更加復雜的情形是DSL本身提供的抽象無法滿足全部需求,而需要在局部補充更多模型之外的信息,例如物品接收單審批通過后自動導入庫存等。
     
       在Witrix中,代碼生成不是直接產生最終的輸出,而是在編譯期生成基礎模型,它與補充描述通過extends算子進行融合運算之后產生最終輸出, 這種融合可以實現基礎功能的新增,更改或者刪除。典型的調用形式為

      
    <biz-flow>
           
    <extends>
             
    <flow_cp:StepFlow3>
               
    <step id="check" userField="checker" />
              
    </flow_cp:StepFlow3>
           
    </extends>
           
           
    <action id="pass_approve">
             .
           
    </action>
       
    </biz-flow>

    這里的操作過程可以看作是BizFlow extends SeqFlow<FlowConfig extends StepFlow3Config>,與泛型技術非常類似,只是需要更強的局部結構控制能力。
        按照級列理論http://canonical.javaeye.com/blog/33824 ,我們可以定義一個DSL的級列,整個抽象過程為
         Context0 + DSL1 + EXT0 = DSL0
         Context1 + DSL2 + EXT1 = DSL1
           

        在目前一些通用語言中,也有一些所謂內嵌DSL的方案,可以提供比較簡潔的業務描述。但是僅僅建立DSL描述是不充分的,從級列理論的觀點看,我們必須提供一種DSL的補充手段,能夠在細節處補充DSL模型之外的信息,實現兩者的自然融合。同時我們應該可以在不同的抽象層面上獨立的進行操作,例如在 DSL1和DSL2的層面上都可以通過類似繼承的操作實現局部調整,這同時也包括在不同的抽象層面上都能對模型進行合法性校驗。
       
    主站蜘蛛池模板: 色欲aⅴ亚洲情无码AV蜜桃| 亚洲另类春色校园小说| 黄色免费网站在线看| 成人免费无码大片a毛片软件| 精品亚洲AV无码一区二区三区| 久久久免费的精品| 亚洲好看的理论片电影| 久久综合国产乱子伦精品免费| 亚洲日本一区二区| 综合在线免费视频| 亚洲夂夂婷婷色拍WW47| 日本高清免费不卡在线| 男人免费视频一区二区在线观看| 亚洲视频一区二区| 久久aa毛片免费播放嗯啊| 国产精品亚洲精品青青青| 日日操夜夜操免费视频| 一级A毛片免费观看久久精品| 亚洲熟妇无码另类久久久| 中文字幕成人免费视频| 亚洲AV无码精品蜜桃| 国产传媒在线观看视频免费观看| 男女拍拍拍免费视频网站| 7777久久亚洲中文字幕蜜桃| 免费在线观看的网站| 无遮挡呻吟娇喘视频免费播放| 亚洲成在人线av| 成人毛片免费在线观看| 草久免费在线观看网站| 亚洲天堂中文资源| 免费毛片网站在线观看| 91在线视频免费观看| 亚洲狠狠成人综合网| 亚洲天堂中文字幕在线| 亚洲黄色免费电影| 日本精品久久久久久久久免费| 91亚洲国产在人线播放午夜| 四虎永久在线免费观看| 最近中文字幕免费完整| 特黄特色大片免费| 亚洲成A∨人片在线观看无码|