??? 程序生成器可以加快程序編碼產(chǎn)生的速度,產(chǎn)生規(guī)范和正確的代碼,,編寫一個程序生成器,,它意味著不僅僅是寫一個程序,,而是要寫一個可以寫出許多程序的程序。在用戶界面,、數(shù)據(jù)庫,、中間件、語法分析" title="語法分析">語法分析和詞法分析等方面,,程序生成器是其開發(fā)環(huán)境中的重要部分,。程序生成器的思想已經(jīng)使用了很多年了。比如:
. 語法分析器:語法分析器讀入一個標(biāo)記序列,,并且創(chuàng)建一個稱為語法樹的描述信息的數(shù)據(jù)
結(jié)構(gòu),。典型的為UNIX使用程序yacc,它讀入一個語言的形式描述(用某種語法表示)連同看
作是語法規(guī)則的動作,,然后輸出一個語法分析器程序,。
. 有限狀態(tài)機(jī):可以用顯示不同狀態(tài)、事件及狀態(tài)轉(zhuǎn)移的表和(或)圖對程序進(jìn)行描述和說明,。
典型的為UNIX實(shí)用程序lex,,就是一個有限狀態(tài)機(jī)的程序生成器,并且用yacc來解析語言
的標(biāo)記,。
. 用戶界面:現(xiàn)在大多數(shù)代碼都是由GUI構(gòu)造器和直觀的編程工具自動生成,。
. 數(shù)據(jù)庫中的程序生成器:給出數(shù)據(jù)表、關(guān)系,、事務(wù)邏輯及報表模式的描述,,就能生成依照指定的規(guī)格構(gòu)造的數(shù)據(jù)庫程序。如:報表生成器,、菜單生成器,、屏幕生成器等。
. Web頁面生成:Java服務(wù)器頁面JSP是一種在Web上創(chuàng)建動態(tài)內(nèi)容的工具,。
??? 而XML作為一種完全可移植的數(shù)據(jù)格式,,將成為跨平臺的不同系統(tǒng)之間的數(shù)據(jù)交換及數(shù)據(jù)顯示、描述的標(biāo)準(zhǔn),。Java具有面向?qū)ο?、跨平臺、分布式、簡捷,、健壯,、安全等特點(diǎn),功能強(qiáng)大且簡單易學(xué),,正在逐步成為新一代網(wǎng)絡(luò)編程的主要開發(fā)語言,,Java將是網(wǎng)絡(luò)上的“世界語”,今后所有用其它語言編寫的軟件統(tǒng)統(tǒng)都要用Java語言來改寫,。XML和Java的結(jié)合對已有的程序生成器技術(shù)提供了新的應(yīng)用背景,,并且兩者相互協(xié)調(diào)補(bǔ)充。以更簡單而且優(yōu)雅的風(fēng)格,、可靠的性能,,提高程序生成器的開發(fā)效率。
2?程序生成器的結(jié)構(gòu)
??? 作為程序生成器的典型結(jié)構(gòu),,它由獲取數(shù)據(jù),、分析/轉(zhuǎn)換數(shù)據(jù)、生成程序3個部分組成,。規(guī)范程序生成器經(jīng)過如圖1所示三種約束時間,,完成程序的生成。
3?域工程技術(shù)
??? 域工程是一個用于高效創(chuàng)建一個應(yīng)用(程序或軟件組件)族成員的過程,。它是一個確定某個專業(yè)的重要組成與需求的系統(tǒng)方法,,對如何高效地建立一個滿足用戶需要的程序生成器是非常必要的。程序的自動創(chuàng)建依賴于對語法和期望目標(biāo)的精確描述,,域工程技術(shù)將此概念延伸到時間基礎(chǔ)上分析一系列相關(guān)的程序,,并能夠生成和修改它們。生成系統(tǒng)的構(gòu)造過程就是一個解決問題產(chǎn)生軟件程序過程,。因此,,域既是一個有關(guān)聯(lián)的問題的集合,也是一個有關(guān)的軟件應(yīng)用程序" title="應(yīng)用程序">應(yīng)用程序的集合,。域工程分為兩個過程:域分析及域?qū)崿F(xiàn),。
??? 域分析:是一個用于確定域的術(shù)語、范圍,、共性及變性的過程,。
??? 域?qū)崿F(xiàn):是指在域中按照指定的要求高效構(gòu)造應(yīng)用及創(chuàng)建工具, 在域分析結(jié)束時即開始。這其中包括程序生成器,。
??? 任何開發(fā)過程都要經(jīng)歷一系列的決策,。在需求分析、軟件結(jié)構(gòu),、界面開發(fā),、軟件設(shè)計(jì)(算法、數(shù)據(jù)結(jié)構(gòu)" title="數(shù)據(jù)結(jié)構(gòu)">數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)表示)、軟件編碼與測試以及軟件的使用過程中都需要做出決策,。有關(guān)的最艱難的工作是做出決策而不是編碼,。對于域工程,最困難的是判斷哪些是重要的決策,,由誰來制定,什么時候制定,。并且要能區(qū)分其中的重要決策和不重要決策,。決策的制定,要考慮域工程的過程中下列三種重要角色的作用及其作用時間(約束時間),。
??? 域工程師:定義并建立如程序生成器那樣的過程和工具,。
??? 應(yīng)用工程師:利用如程序生成器那樣的工具創(chuàng)建應(yīng)用程序。
??? 應(yīng)用程序用戶:使用應(yīng)用程序,。
??? 域工程時間:由域工程師為每個應(yīng)用程序族做出決策的時間,。包括:域分析時間,域執(zhí)行時間,。
??? 約束時間:由應(yīng)用工程師為每個應(yīng)用程序做出決策的時間,。包括:規(guī)劃時間,生成時間,,編譯時間,,設(shè)計(jì)時間,鏈接時間,。
??? 運(yùn)行時間:由應(yīng)用程序用戶為每個特定的使用做出決策的時間,。包括:安裝時間,初始化時間,,真正運(yùn)行時間,。
??? 決策分解是域?qū)崿F(xiàn)的基本概念,它簡單地分解每個獨(dú)立的決策,,并將其作為一個獨(dú)立元素或系統(tǒng)組件,。如決策的物理分解可產(chǎn)生3種信息:域信息、用戶信息,、應(yīng)用信息,。有效的決策分解將產(chǎn)生一個既易于改變、又易于構(gòu)造的軟件結(jié)構(gòu),。決策分解基于抽象化,。抽象化是一種使軟件更具有一般性、靈活性,、可理解性和可重用性的主要技術(shù),。
??? 決策分解技術(shù)主要包括:
(1)?物理分解:如,應(yīng)用程序可以分解出不依賴于機(jī)器的部分和依賴于機(jī)器的部分。
(2)?典型過程的抽象化:如,,子程序,、宏及可重用軟件包的創(chuàng)建。
(3)?面向?qū)ο蟮某橄蠡喝?,隱含在對象中的隱藏決策,。
(4)?繼承方法:公共關(guān)系在父類和子類中被共享使用。
(5)?應(yīng)用程序框架:可看作一個軟件重用的自頂向下的方法,。
(6)?規(guī)范驅(qū)動技術(shù):應(yīng)用規(guī)范層信息創(chuàng)建或直接執(zhí)行應(yīng)用程序
??? 域工程是創(chuàng)建應(yīng)用程序族的過程,,因此,不僅要考慮單一的應(yīng)用會如何隨時間而改變,,而且也要注意到域領(lǐng)域應(yīng)用的整個范圍,,從而確定這些應(yīng)用之間的差別。這些差別稱為域工程的可變性,,它是域工程的核心,。對于域工程需要理解一個應(yīng)用族中什么是不變的,什么是可變的,。不變的成分稱為共性,,最困難的就是確定并組織一個域的所有共性與可變性。
共性:是一個在域工程期間關(guān)于什么是整個域的共同性問題所做出的決策或假設(shè),。共性可以確定域的范圍,、軟件的功能、與其它域的分界面,、操作環(huán)境,、軟件的限制標(biāo)準(zhǔn)以及應(yīng)用軟件公共部分實(shí)現(xiàn)的細(xì)節(jié)。共性和標(biāo)準(zhǔn)有許多共同點(diǎn),。標(biāo)準(zhǔn)是做某件事情的共同方法,。許多為標(biāo)準(zhǔn)所做的努力根本上就是一個域分析。相反域分析工作附帶產(chǎn)生一些標(biāo)準(zhǔn),,以幫助創(chuàng)建更大的將為一大群人所接受的共性集合,。
??? 可變性:是一個在域分析期間確認(rèn)但直到建立或運(yùn)行時間才確定的決策。
共性和可變性經(jīng)??梢韵嗷マD(zhuǎn)化,。而使域分析保持平衡。如圖2所示
??? 可變性包括:建立時的可變性,、運(yùn)行時的可變性,,編譯時可變性、生成時可變性,、預(yù)處
理時可變性,。
??? ① 建立時的可變性
??? 表示程序族的全部程序中的差別是什么,。建立時的可變性集合是為建立一個程序生成器所需要的信息中最重要的部分,它可以用于定義一個規(guī)范語言和一個支持可變性的結(jié)構(gòu)框架,。
??? ②?運(yùn)行時的可變性
??? 是在運(yùn)行時間內(nèi)確定的決策,。運(yùn)行時的可變性建立在應(yīng)用軟件的公共部分。由許多方法表示和控制,。比如:
. 資源和配置文件:這些文件包含信息并在運(yùn)行時間內(nèi)讀入一般保存在一個外部文件
. 數(shù)據(jù)庫:查詢數(shù)據(jù)庫獲得讀入信息
. 用戶界面:通過與用戶交互獲得信息,。
. 動態(tài)加載類:常見的變化可以被確定、創(chuàng)建,、編譯,,并且直接加載到一個正在運(yùn)行的Java程序中。
??? ③?編譯時可變性
??? 是在編譯時間確定決策,。可以由許多方式實(shí)現(xiàn),。比如:
. 編譯時的常量:可以利用好的編譯器來優(yōu)化程序,。
. 面向?qū)ο蠹夹g(shù):基本類定義共性,子類提供可變性,。特別是編譯時的可變性,。
??? ④?生成時可變性
??? 信息通過一個創(chuàng)建定制程序的程序生成器讀入。
??? ⑤?預(yù)處理時可變性
??? 預(yù)處理發(fā)生在編譯時間前,,預(yù)處理器用于擴(kuò)展宏功能,。依據(jù)分開的頭文件給程序構(gòu)造可變性。
??? 域工程經(jīng)常從應(yīng)用工程周期獲得適當(dāng)?shù)姆答伓粩嗾归_,。形成域工程周期,。應(yīng)用工程周期和域工程周期的關(guān)系如圖3所示。
4?程序生成器的實(shí)現(xiàn)方法
4.1 利用DOM生成程序
??? 使用XML文件和DOM構(gòu)建一個程序生成器如圖4所示,。
??? 使用XML語法分析器讀入和存儲規(guī)范, 讀入XML文件并對其進(jìn)行語法分析,,創(chuàng)建DOM對象。XML語法分析器需要三種分析和存儲規(guī)范的輸入方法:
. 由W3C提供的DOM接口的輸入(純DOM方法),;
. 針對IBM的語法分析器的輸入(自定義DOM方法),;
. 用于讀入文件的標(biāo)準(zhǔn)的Java輸入數(shù)據(jù)包(自定義SAX方法);
??? 以上三種分析和存儲規(guī)范方法的選擇可以結(jié)合下面的判定要求加以確定,。
(1) 判定代碼生成器能否用自定義數(shù)據(jù)結(jié)構(gòu)獲得規(guī)范的信息,,若不能,則使用純DOM方法,;若能,,則進(jìn)一步判定自定義數(shù)據(jù)結(jié)構(gòu)是否應(yīng)該從DOM中創(chuàng)建,若是,,則使用自定義DOM方法,。否則,,使用自定義SAX方法;
(2)?根據(jù)性能要求確定,。大的XML文檔上使用DOM數(shù)據(jù)結(jié)構(gòu)可能會花費(fèi)昂貴,,尤其是當(dāng)僅僅使用文檔的一小部分生成程序時。這時將不得不創(chuàng)建自己的自定義數(shù)據(jù)結(jié)構(gòu),,并且還將使用SAX,。
(3)?如果使用DOM效率很低,也可以根據(jù)實(shí)際情況加以考慮,。這種情況最有可能發(fā)生在程序的規(guī)范僅為大的XML文檔的一小部分的地方,。使用SAX將允許忽略XML文檔中的大部分,而僅僅只為代碼生成器提取必要的信息,。
??? 一旦XML文檔進(jìn)行過語法分析并且作為一個對象使用時,,就可以在該對象上執(zhí)行分析和判斷。分析包括:
. 檢錯:在規(guī)范中查找句法錯誤,。
. 警告:查找公共錯誤或潛在的不明顯的錯誤,。
. 模型分析:分析規(guī)范更深層的語義。
. 性能分析:決定生成一個優(yōu)化程序結(jié)構(gòu)或代碼途徑的規(guī)范,。
. 縮寫的擴(kuò)展:規(guī)范中常提供縮寫或快捷方式,。
. 擴(kuò)展成標(biāo)準(zhǔn)形式:有些規(guī)范允許以各種方式說明同一件事情。
. 優(yōu)化:轉(zhuǎn)換對象,。
??? 一旦DOM數(shù)據(jù)結(jié)構(gòu)存儲于內(nèi)存中,,就可以把基于XML文檔的代碼用于分析和轉(zhuǎn)換結(jié)構(gòu),最終代碼生成器直接從DOM數(shù)據(jù)結(jié)構(gòu)中獲取信息,。讀入XML文件并對其進(jìn)行語法分析的程序段如下:
import? com.ibm.xml.parser.Parser;
import? org.w3c.dom.*;
import? java.io.*;
public? class? DOM_Utill {
…
/** read? and? parse? an? XML? files */
public? static? Document? readDocument (String? filename)
throws Exception {
InputStream is=new FileInputStream(filename);
Parser parser=new Parser(filename);
Return Parser.readStream(is);
}
}
??? 使用DOM的程序生成器,,首先要提供一個基本實(shí)用工具類,該類定義利用DOM樹中信息的實(shí)用方法,,如用于獲取與語法分析樹中的節(jié)點(diǎn)相關(guān)聯(lián)的數(shù)據(jù)的方法,,用于獲取元素屬性值的方法,如果使用自定義DOM方法,。這種方法是程序?qū)裍ML規(guī)范作為一個自定義的數(shù)據(jù)結(jié)構(gòu)讀入,,然后將該規(guī)范轉(zhuǎn)換為一個自定義的數(shù)據(jù)結(jié)構(gòu),XML規(guī)范既可以在運(yùn)行時間讀入,,也可以在生成時間讀入,。標(biāo)準(zhǔn)的代碼生成器是一系列簡單的打印語句,這些語句是具有重復(fù)代碼或條件代碼的控制語句的狀態(tài)流,。
4.2 利用JSP(Java? Server? Pages)生成程序
??? JSP是普遍應(yīng)用于Internet中的重要的程序生成器,。JSP是一種非常簡單的規(guī)范語言,包含了輸出到Web頁面的靜態(tài)文本和調(diào)用基本實(shí)現(xiàn)語言的轉(zhuǎn)義符" title="轉(zhuǎn)義符">轉(zhuǎn)義符,,它沒有高層次的抽象化并且不涉及語言結(jié)構(gòu),。轉(zhuǎn)義符提供很大的靈活性,,同時又只產(chǎn)生最小的影響。JSP是一種既簡單又強(qiáng)有力的技術(shù),,用于在Web服務(wù)器端生成動態(tài)的HTML頁面,。JSP提供了一個非常簡單的利用“模板”創(chuàng)建程序生成器的途徑。盡管JSP是用于設(shè)計(jì)和實(shí)現(xiàn)Web頁面的,,但原則上可以傳送任何其它內(nèi)容,,特別是它可以傳送Java程序。
一個簡單的程序生成器是JSP翻譯器,,JSP翻譯器是程序生成器廣泛使用的一個示例,。它把一個JSP文件(規(guī)范)轉(zhuǎn)換成一個JAVA文件。從一個JSP文件到Java程序的轉(zhuǎn)換由Java服務(wù)器頁面規(guī)范來定義,。過程示例如下:
Mydate.jsp
?
???
4.3 利用Xpath和XSLT生成程序
??? XSLT和Xpath能夠不利用任何Java代碼就可以創(chuàng)建程序生成器,。
?? ?Xpath是一種用于從XML文檔提取信息的語言,用于在XSLT中選擇一個XML文檔的不同部分,。
??? XSLT又稱可擴(kuò)展的樣式表轉(zhuǎn)換語言,,可以將XML文檔翻譯成其它不同結(jié)構(gòu)的XML文檔或純文本文件。XSLT提供了一種轉(zhuǎn)換和操作XML數(shù)據(jù)的機(jī)制,。如圖5所示。
??? XML構(gòu)成了信息互交換標(biāo)準(zhǔn)的基礎(chǔ),。XML提供了信息構(gòu)成的結(jié)構(gòu),,XSLT與Xpath(XML路徑語言)提供了提取、重建和熟練使用XML中信息的手段,。Xpath使用一種簡單的路徑語言來對XML文檔的各個部分進(jìn)行尋址,,XML提供一系列的操作和操作方法。而Xpath保證了選擇和尋址的準(zhǔn)確度,。
??? 利用Xpath和XSLT生成程序舉例
play.xml
?
???
???
?
???
???
?
?
???
???
?
?
???