孫淑娟,牟德昆
(煙臺職業(yè)學(xué)院,山東 煙臺 264001)
通過開發(fā)W indow s語音助手軟件,從軟件設(shè)計分析中得出該軟件分為三個核心模塊:語音引擎、語義分析、輔助操作。輔助操作模塊的設(shè)定目的是用程序替代人完成日常的手工操作,在研究實現(xiàn)中發(fā)現(xiàn)功能需要進行Window s基本操作、常用軟件的操作,如果要實現(xiàn)之,輔助操作的范圍將是一個很大的范疇,特別是其中常用軟件隨著時間的變化而有可能增加,所涉及的范圍不容易界定,這樣給軟件的開發(fā)帶來擴展的要求。需要一種模式,不影響并可復(fù)用前期開發(fā)的軟件成果,而且能夠與前期開發(fā)無縫銜接,最好不用對前期開發(fā)重新編譯便可使前期開發(fā)使用到的新技術(shù),又可最大限度的利用前期開發(fā)中的成果。
軟插件作為軟件的一種集成機制,具有以下特征:①模塊性好,獨立性強;②可靠性好;③內(nèi)部功能的高效實現(xiàn);④連接簡單,使用方便;⑤有封裝功能;⑥清晰、簡明的說明。
使用軟插件模式的例子有很多,如著名的Java開發(fā)環(huán)境Eclipse就是一個最典型的使用軟插件模式的軟件,各種插件集中在Eclipse的一個名稱為p lugins的文件夾中,以*.jar形式打包,通常還都配有相應(yīng)配置文件p lugin.xm l用于提供插件的配置參數(shù)信息。Eclipse在啟動時自動掃描此文件夾,并裝入各種組件。又如圖像處理軟件Pho toshop用于實現(xiàn)圖像特效的濾鏡,也是軟插件技術(shù)裝載的。
通過分析,決定使用軟插件模式來開發(fā)輔助操作部分,使系統(tǒng)可以承受輔助操作的功能變化。在實現(xiàn)的過程中模仿了Eclipse的插件體系,使用的核心技術(shù)是反射。
1.1 反射
反射是面向?qū)ο蠹夹g(shù)的一個重要發(fā)展,技術(shù)特點是允許一個對象的類型到程序運行時才確定,這樣源代碼中部分代碼所要創(chuàng)建的對象類型是動態(tài)可變的。在動態(tài)創(chuàng)建對象之后,使用反射技術(shù)還可以動態(tài)地調(diào)用對象的方法。
在C#中,通過反射可以在運行時獲得.Net中每一個類型的成員,包括方法、屬性、事件以及構(gòu)造函數(shù)等,還可以獲得每個成員的名稱、參數(shù)等。如果獲得了構(gòu)造函數(shù)的信息,即可直接創(chuàng)建對象,即使這個對象的類型在編譯時還不知道。
程序代碼在編譯后生成可執(zhí)行的應(yīng)用程序,.Net的應(yīng)用程序結(jié)構(gòu)分為程序域—程序集—模塊—類型—成員幾個層次。程序集包含模塊,而模塊包含類型,類型又包含成員。反射提供了封裝程序集、模塊和類型的對象??梢允褂梅瓷鋭討B(tài)地創(chuàng)建類型的實例,將類型綁定到現(xiàn)有對象,或從現(xiàn)有對象中獲取類型。然后,可以調(diào)用類型的方法或訪問其字段和屬性。
(1)使用A ssembly類的靜態(tài)方法Load From()創(chuàng)建A ssembly對象。用于加載指定的程序集,并得到一個程序集對象,可從此程序集中查找類型并創(chuàng)建該類型的實例。
(2)使用A ssembly對象的Create Instance()方法創(chuàng)建指定類型的對象Obj。Create Instance方法在創(chuàng)建一個具有無參數(shù)默認構(gòu)造函數(shù)的對象時比較方便,其定義:Public object Create Instance(string typename)。當然待創(chuàng)建對象的類必須包含在該程序集中。
(3)使用Obj.Get Type()獲取類型對象_type。
(4)使用_type.GetM ethod()得到M ethod Info對象m td。根據(jù)已知方法的名稱、返回類型、訪問修飾符(p rivate、public)等特征找到指定方法,并得到可發(fā)現(xiàn)指定方法的屬性和訪問方法元數(shù)據(jù)的對象m td。
(5)使用m td.Invoke()方法調(diào)用方法。調(diào)用由M ethod Info實例m td反射的方法。
1.2 關(guān)鍵類說明
1.2.1 Type類
Type類是C#中一種特殊的類型,是用于表達數(shù)據(jù)類型信息的數(shù)據(jù)類型,也是訪問元數(shù)據(jù)的主要方式。使用 Type的成員獲取關(guān)于類型聲明的信息,如構(gòu)造函數(shù)、方法、字段、屬性 (Property)和類的事件。
1.2.2 創(chuàng)建Type對象
.Net Framework所有的類都派生于Object類,Object類提供的 GetType()方法,可以通過對象調(diào)用GetType()獲取其類的信息。
1.2.3 查詢類的方法
Type類 GetM ethods()方法可以用于獲取類型所有方法的清單,返回值是M ethod Info類型數(shù)組。也可以按給定方法名,獲得該方法的M ethod Info對象,例子:
2.1 類的設(shè)計
Window s語音助手是根據(jù)用戶的語音,用輔助操作來代替用戶應(yīng)該進行的手工操作,而這些輔助操作的實現(xiàn)將以程序方法實現(xiàn),需要調(diào)用方法的個數(shù)可能是一個也可能是多個,可以說語音助手進行輔助操作時就是調(diào)用相應(yīng)功能實現(xiàn)的方法。
2.2 具體實現(xiàn)
輔助操作模塊的核心是動態(tài)代理中心(Proxy類),該類集中所有與動態(tài)調(diào)用方法相關(guān)的模塊程序。
2.2.1 初始化運行環(huán)境
(1)讀取項目運行所需的所有配置文檔。配置文檔是在項目文件夾下的p lugins文件夾中所有XML文檔,配置文檔有兩類。
●程序集的配置文檔,文件后綴統(tǒng)一為-p lugins.xm l,內(nèi)容樣例如下:
●輔助操作的動作說明文檔,文件后綴統(tǒng)一為-actions.xm l,內(nèi)容樣例如下:
在.Net中,DataSet類擁有非常完善的對XML文檔進行操作的方法,如ReadXm l方法,可以將XML架構(gòu)和數(shù)據(jù)讀入到DataSet對象中,并轉(zhuǎn)換為數(shù)據(jù)表的形式。在項目啟動時,程序使用數(shù)據(jù)集DataSet對象讀取XML文檔,完成XML數(shù)據(jù)到表數(shù)據(jù)的轉(zhuǎn)換,并根據(jù)類之間的關(guān)系,建立DataRelation對象以確立表之間的父/子關(guān)系,為后續(xù)工作中讀取和查找配置文檔中的信息做準備。
(2)根據(jù)數(shù)據(jù)集DataSet中的配置信息加載所有程序集
在開發(fā)輔助操作所涉及替代手工操作方法的時候,根據(jù)方法功能相近的原則,將方法模塊分類后集中成為類庫。類庫的文件擴展名為DLL文件,項目啟動后,通過加載的配置信息找到對應(yīng)的DLL文件,并加載后形成A ssem bly類的對象集合。
2.2.2 查找對應(yīng)的動作信息
項目的語義分析模塊會根據(jù)語音引擎提供的用戶語句進行分析,得出需要的關(guān)鍵字,例如用戶語句為“最大化記事本”,可得出動作關(guān)鍵字“最大化”,參數(shù)關(guān)鍵字“記事本”。根據(jù)分析結(jié)果,在數(shù)據(jù)集DataSet對象中的Action表里,使用動作關(guān)鍵字“最大化”在動作描述信息字段descrip tion中進行比對,查找出對應(yīng)記錄,再通過已經(jīng)建立好的表之間的父/子關(guān)系,找到完成該動作所需的方法信息,以及執(zhí)行方法所需的參數(shù)信息,并將信息匯集到Action對象中,這樣執(zhí)行用戶語句命令所需的配置信息準備完畢。
2.2.3 參數(shù)值的修正
語義分析得出的參數(shù),由于是從文本語句中得來,所以參數(shù)值的類型是String類型,而方法執(zhí)行時參數(shù)的要求不是String類型所能滿足的,修正的目的是讓參數(shù)能最大限度地符合程序運行的要求。
(1)類型修正
某些方法在運行時需要的類型可能是如Int32、DateTime等其他類型,所以在傳遞參數(shù)之前要將分析得到的參數(shù)值轉(zhuǎn)換成參數(shù)信息中規(guī)定的類型。做法是如Int32、DateTime等常用類型中都有Parse方法,該方法的功能將指定字符串轉(zhuǎn)換成規(guī)定類型??梢允褂梅瓷浼夹g(shù)生成指定類型,并在該類型的Type對象中查找到Parse方法的說明—M ethod Info對象,回調(diào)該方法完成參數(shù)值的類型轉(zhuǎn)換。類型修正是整個參數(shù)修正的基礎(chǔ)。
(2)參數(shù)修正
參數(shù)修正是根據(jù)語義分析所得的用戶命令、該方法的參數(shù)說明信息、參數(shù)初值、要完成動作所需所有方法的返回值進行修正的,主要分3種情況。
●該參數(shù)值使用的是前面方法的返回值。在文檔中,這種情況使用“#”開頭的數(shù)字標記,例如:〈Parameter name="w in Title"type="System.String"Value="#0"/〉
這個參數(shù)使用的是第一個方法的返回值,處理時直接進行賦值。
●該參數(shù)有初值。例如:〈Parameter name="w in Title"type="System.Int32"Value="2"/〉,將初值進行類型轉(zhuǎn)換后使用
●沒有初值的,使用命令中所含有的參數(shù)值,并按所需類型轉(zhuǎn)換。
2.2.4 執(zhí)行完成動作所需的方法
TransferMethod方法是Proxy類的核心方法,它的任務(wù)是根據(jù)分析得到的用戶命令執(zhí)行對應(yīng)的輔助操作中規(guī)定所有方法。具體的步驟是首先依據(jù)用戶命令中的關(guān)鍵字查找動作說明信息Action,提取方法的說明信息以及其參數(shù)的說明信息。然后通過比對名稱空間namespace,在程序集集合中找到對應(yīng)A ssembly對象,修正參數(shù)值后,使用反射執(zhí)行該方法。
在整個開發(fā)過程中軟插件模式體現(xiàn)出很多優(yōu)點,它使輔助操作部分和主程序之間徹底分離開來,功能方法可獨立開發(fā),項目組間的影響減少。在后期的升級中輔助操作上的變化,只要改動XM L配置文檔和配屬新的對應(yīng)DLL類庫,程序重新啟動后即可擁有新的功能,升級簡便。它使系統(tǒng)擁有了一個開放的組件識別和裝載體系,在這種體系下,實現(xiàn)了將用戶常用的連續(xù)命令記錄成XML配置信息保存下來,合成一個新的動作命令,這樣做可以允許用戶按自己的需要組合新的功能,方便了用戶的操作。
[1]金旭亮.Net2.0面向?qū)ο缶幊探颐豙M].北京:電子工業(yè)出版社,2007.
[2]李豐,陳英,鄔延風(fēng).基于領(lǐng)域復(fù)用的軟插件庫應(yīng)用研究[J].北京理工大學(xué)學(xué)報,1998,18(6):771-774.
[3]石美紅,毛江輝,延偉偉,等.在Window s平臺下開發(fā) Ethereal插件的方法與實現(xiàn)[J].計算機應(yīng)用研究,2006,(10):234 -237.