孫淑娟,牟德昆
(煙臺職業學院,山東 煙臺 264001)
通過開發W indow s語音助手軟件,從軟件設計分析中得出該軟件分為三個核心模塊:語音引擎、語義分析、輔助操作。輔助操作模塊的設定目的是用程序替代人完成日常的手工操作,在研究實現中發現功能需要進行Window s基本操作、常用軟件的操作,如果要實現之,輔助操作的范圍將是一個很大的范疇,特別是其中常用軟件隨著時間的變化而有可能增加,所涉及的范圍不容易界定,這樣給軟件的開發帶來擴展的要求。需要一種模式,不影響并可復用前期開發的軟件成果,而且能夠與前期開發無縫銜接,最好不用對前期開發重新編譯便可使前期開發使用到的新技術,又可最大限度的利用前期開發中的成果。
軟插件作為軟件的一種集成機制,具有以下特征:①模塊性好,獨立性強;②可靠性好;③內部功能的高效實現;④連接簡單,使用方便;⑤有封裝功能;⑥清晰、簡明的說明。
使用軟插件模式的例子有很多,如著名的Java開發環境Eclipse就是一個最典型的使用軟插件模式的軟件,各種插件集中在Eclipse的一個名稱為p lugins的文件夾中,以*.jar形式打包,通常還都配有相應配置文件p lugin.xm l用于提供插件的配置參數信息。Eclipse在啟動時自動掃描此文件夾,并裝入各種組件。又如圖像處理軟件Pho toshop用于實現圖像特效的濾鏡,也是軟插件技術裝載的。
通過分析,決定使用軟插件模式來開發輔助操作部分,使系統可以承受輔助操作的功能變化。在實現的過程中模仿了Eclipse的插件體系,使用的核心技術是反射。
1.1 反射
反射是面向對象技術的一個重要發展,技術特點是允許一個對象的類型到程序運行時才確定,這樣源代碼中部分代碼所要創建的對象類型是動態可變的。在動態創建對象之后,使用反射技術還可以動態地調用對象的方法。
在C#中,通過反射可以在運行時獲得.Net中每一個類型的成員,包括方法、屬性、事件以及構造函數等,還可以獲得每個成員的名稱、參數等。如果獲得了構造函數的信息,即可直接創建對象,即使這個對象的類型在編譯時還不知道。
程序代碼在編譯后生成可執行的應用程序,.Net的應用程序結構分為程序域—程序集—模塊—類型—成員幾個層次。程序集包含模塊,而模塊包含類型,類型又包含成員。反射提供了封裝程序集、模塊和類型的對象。可以使用反射動態地創建類型的實例,將類型綁定到現有對象,或從現有對象中獲取類型。然后,可以調用類型的方法或訪問其字段和屬性。
(1)使用A ssembly類的靜態方法Load From()創建A ssembly對象。用于加載指定的程序集,并得到一個程序集對象,可從此程序集中查找類型并創建該類型的實例。
(2)使用A ssembly對象的Create Instance()方法創建指定類型的對象Obj。Create Instance方法在創建一個具有無參數默認構造函數的對象時比較方便,其定義:Public object Create Instance(string typename)。當然待創建對象的類必須包含在該程序集中。
(3)使用Obj.Get Type()獲取類型對象_type。
(4)使用_type.GetM ethod()得到M ethod Info對象m td。根據已知方法的名稱、返回類型、訪問修飾符(p rivate、public)等特征找到指定方法,并得到可發現指定方法的屬性和訪問方法元數據的對象m td。
(5)使用m td.Invoke()方法調用方法。調用由M ethod Info實例m td反射的方法。
1.2 關鍵類說明
1.2.1 Type類
Type類是C#中一種特殊的類型,是用于表達數據類型信息的數據類型,也是訪問元數據的主要方式。使用 Type的成員獲取關于類型聲明的信息,如構造函數、方法、字段、屬性 (Property)和類的事件。
1.2.2 創建Type對象
.Net Framework所有的類都派生于Object類,Object類提供的 GetType()方法,可以通過對象調用GetType()獲取其類的信息。
1.2.3 查詢類的方法
Type類 GetM ethods()方法可以用于獲取類型所有方法的清單,返回值是M ethod Info類型數組。也可以按給定方法名,獲得該方法的M ethod Info對象,例子:

2.1 類的設計
Window s語音助手是根據用戶的語音,用輔助操作來代替用戶應該進行的手工操作,而這些輔助操作的實現將以程序方法實現,需要調用方法的個數可能是一個也可能是多個,可以說語音助手進行輔助操作時就是調用相應功能實現的方法。
2.2 具體實現
輔助操作模塊的核心是動態代理中心(Proxy類),該類集中所有與動態調用方法相關的模塊程序。
2.2.1 初始化運行環境
(1)讀取項目運行所需的所有配置文檔。配置文檔是在項目文件夾下的p lugins文件夾中所有XML文檔,配置文檔有兩類。
●程序集的配置文檔,文件后綴統一為-p lugins.xm l,內容樣例如下:

●輔助操作的動作說明文檔,文件后綴統一為-actions.xm l,內容樣例如下:

在.Net中,DataSet類擁有非常完善的對XML文檔進行操作的方法,如ReadXm l方法,可以將XML架構和數據讀入到DataSet對象中,并轉換為數據表的形式。在項目啟動時,程序使用數據集DataSet對象讀取XML文檔,完成XML數據到表數據的轉換,并根據類之間的關系,建立DataRelation對象以確立表之間的父/子關系,為后續工作中讀取和查找配置文檔中的信息做準備。
(2)根據數據集DataSet中的配置信息加載所有程序集
在開發輔助操作所涉及替代手工操作方法的時候,根據方法功能相近的原則,將方法模塊分類后集中成為類庫。類庫的文件擴展名為DLL文件,項目啟動后,通過加載的配置信息找到對應的DLL文件,并加載后形成A ssem bly類的對象集合。
2.2.2 查找對應的動作信息
項目的語義分析模塊會根據語音引擎提供的用戶語句進行分析,得出需要的關鍵字,例如用戶語句為“最大化記事本”,可得出動作關鍵字“最大化”,參數關鍵字“記事本”。根據分析結果,在數據集DataSet對象中的Action表里,使用動作關鍵字“最大化”在動作描述信息字段descrip tion中進行比對,查找出對應記錄,再通過已經建立好的表之間的父/子關系,找到完成該動作所需的方法信息,以及執行方法所需的參數信息,并將信息匯集到Action對象中,這樣執行用戶語句命令所需的配置信息準備完畢。
2.2.3 參數值的修正
語義分析得出的參數,由于是從文本語句中得來,所以參數值的類型是String類型,而方法執行時參數的要求不是String類型所能滿足的,修正的目的是讓參數能最大限度地符合程序運行的要求。
(1)類型修正
某些方法在運行時需要的類型可能是如Int32、DateTime等其他類型,所以在傳遞參數之前要將分析得到的參數值轉換成參數信息中規定的類型。做法是如Int32、DateTime等常用類型中都有Parse方法,該方法的功能將指定字符串轉換成規定類型。可以使用反射技術生成指定類型,并在該類型的Type對象中查找到Parse方法的說明—M ethod Info對象,回調該方法完成參數值的類型轉換。類型修正是整個參數修正的基礎。


(2)參數修正
參數修正是根據語義分析所得的用戶命令、該方法的參數說明信息、參數初值、要完成動作所需所有方法的返回值進行修正的,主要分3種情況。
●該參數值使用的是前面方法的返回值。在文檔中,這種情況使用“#”開頭的數字標記,例如:〈Parameter name="w in Title"type="System.String"Value="#0"/〉
這個參數使用的是第一個方法的返回值,處理時直接進行賦值。
●該參數有初值。例如:〈Parameter name="w in Title"type="System.Int32"Value="2"/〉,將初值進行類型轉換后使用
●沒有初值的,使用命令中所含有的參數值,并按所需類型轉換。
2.2.4 執行完成動作所需的方法
TransferMethod方法是Proxy類的核心方法,它的任務是根據分析得到的用戶命令執行對應的輔助操作中規定所有方法。具體的步驟是首先依據用戶命令中的關鍵字查找動作說明信息Action,提取方法的說明信息以及其參數的說明信息。然后通過比對名稱空間namespace,在程序集集合中找到對應A ssembly對象,修正參數值后,使用反射執行該方法。


在整個開發過程中軟插件模式體現出很多優點,它使輔助操作部分和主程序之間徹底分離開來,功能方法可獨立開發,項目組間的影響減少。在后期的升級中輔助操作上的變化,只要改動XM L配置文檔和配屬新的對應DLL類庫,程序重新啟動后即可擁有新的功能,升級簡便。它使系統擁有了一個開放的組件識別和裝載體系,在這種體系下,實現了將用戶常用的連續命令記錄成XML配置信息保存下來,合成一個新的動作命令,這樣做可以允許用戶按自己的需要組合新的功能,方便了用戶的操作。
[1]金旭亮.Net2.0面向對象編程揭秘[M].北京:電子工業出版社,2007.
[2]李豐,陳英,鄔延風.基于領域復用的軟插件庫應用研究[J].北京理工大學學報,1998,18(6):771-774.
[3]石美紅,毛江輝,延偉偉,等.在Window s平臺下開發 Ethereal插件的方法與實現[J].計算機應用研究,2006,(10):234 -237.