湯艷 馬驍驊 孫萍 王鑫
(中國電子科技集團公司第15研究所,北京 100083)
隨著我國各行業(yè)信息化技術應用的不斷深入和發(fā)展,軟件開發(fā)規(guī)模越來越大。通常,項目需要多人甚至多個團隊一起工作,軟件開發(fā)過程所產生的文檔有時多達幾千甚至上萬頁,另一方面,項目交付時間緊迫又要保證質量,這就對開發(fā)工作的標準化,實施效率文檔質量都提出更高的要求[1]。
目前,在軟件設計階段,市場上存在很多成熟的建模、畫圖工具,為軟件設計文檔提供各種更為直觀的圖形化展示,但軟件設計文檔本身仍主要以手工編制為主。由此,產生了軟件設計文檔的諸多問題。如由于開發(fā)工期緊迫,造成軟件設計文檔粗劣、甚至缺少設計文檔;或由于開發(fā)團隊對設計工作的不重視,開發(fā)人員沒有完全依照設計文檔進行編碼,造成軟件設計文檔與軟件源代碼脫節(jié),設計文檔形同虛設。
本文針對軟件設計文檔缺失或源代碼與設計脫節(jié)的問題,提出了一種基于源代碼的軟件設計模型自動生成工具設計方案和實現方法,通過從源代碼中提取抽象語法樹(Abstract Syntax Tree,AST),逆向生成與軟件代碼結構一致的軟件設計文檔。
文中所介紹的軟件設計模型生成工具主要用于分析源代碼、提取抽象語法樹,并根據源代碼的抽象語法樹逆向生成軟件設計文檔。該工具由源代碼分析和生成設計文檔兩大功能模塊構成,如圖1所示。
圖1 功能模塊劃分
源代碼分析模塊包括:分析源代碼、查看源代碼分析結果、修改源代碼分析結果3個子功能,分別實現以下功能:
(1)分析源代碼。實現對源代碼的分析功能,用于提取源代碼的抽象語法樹結構,包括:包、類、注釋等信息;
(2)查看源代碼分析結果。實現對源代碼分析結果的展示功能,用于查看源代碼中包、類的詳細信息;
(3)修改源代碼分析結果。實現對源代碼分析結果的編輯功能,用于人工維護分析結果中缺失或需要修改的信息。
生成軟件設計模塊包括:生成關系圖、生成設計文檔2個子功能,分別實現以下功能:
(1)生成關系圖。實現對源代碼中包、類、方法之間關聯關系的展示功能;
(2)生成設計文檔。實現根據源代碼分析結果,逆向生成與軟件代碼結構一致的軟件設計文檔的功能。
啟動工具后,為工具指定源代碼所在目錄文件夾,并選擇源代碼的開發(fā)語言,然后執(zhí)行源代碼分析操作。工具完成源代碼分析后,顯示源代碼的抽象語法樹結構,并提供以下功能:
(1)查看分析結果。選擇抽象語法樹上某一節(jié)點,可以查看相應節(jié)點的詳細信息,以及所包含的包、類、方法的清單列表;
(2)修改分析結果。抽象語法樹上各節(jié)點的詳細信息可以在清單列表中進行手動修改;
(3)生成關系圖。選擇抽象語法樹上某一節(jié)點,通過生成關系圖功能,可以生成該節(jié)點與其所有子孫節(jié)點之間的包、類關系圖;
(4)生成設計文檔。選擇抽象語法樹上某一節(jié)點,通過生成設計文檔功能,可以按照修改后的分析結果生成設計文檔,文檔中包含所選節(jié)點及其所有子孫節(jié)點的詳細設計信息,包括:包的劃分及設計、詳細設計兩部分。其中,包的劃分及設計包括:包的劃分、各個包的類圖及說明;詳細設計包括:類的名稱、說明、父類,類中所有屬性的名稱、類型、說明,類中所有方法的函數名、參數、返回值、說明等信息。
軟件設計模型生成工具沒有大量結構化數據的存儲需求,所有數據保存到本地硬盤中,因此不使用數據庫。由于不存在數據安全問題,工具也不需要用戶和權限控制策略。
軟件設計模型生成工具通過讀取源代碼生成軟件設計文檔,僅在客戶機本地就可以完成,不需要聯機操作,因此采用單機結構,不設置服務器端。
為了便于后期的功能維護和擴展升級,軟件設計模型生成工具的系統架構分為表示層和業(yè)務邏輯層。其中,表示層負責與用戶進行信息交互、信息收集以及結果展示等相關功能;業(yè)務邏輯層主要實現提取源代碼抽象語法樹,并將抽象語法樹結構轉化為關系圖和軟件設計文檔等核心業(yè)務邏輯。
系統流程圖如圖 2所示。
圖2 系統流程圖
提取抽象語法樹是建立軟件代碼結構的前提。抽象語法樹中保存了軟件代碼的所有信息,通過對語法樹進行深度優(yōu)先遍歷或廣度優(yōu)先遍歷,就可以根據實際需求,在不同層次和維度上獲取軟件代碼結構以及各個包、類、方法之間的邏輯關系[2]。
提取抽象語法樹是一個非常復雜的過程,為了提高開發(fā)效率,本文使用已有開源工具實現抽象語法樹的提取功能。使用已有的成熟工具實現相關功能,在提高開發(fā)效率的同時,也在一定程度上保證了軟件的質量。
軟件設計模型生成工具,分別使用PMD(Programming Mistake Detector)和ANTLR(Another Tool for Language Recognition)工具實現Java代碼、C/C++代碼的抽象語法樹提取功能。
PMD是一個開源靜態(tài)代碼審查工具,可以在不運行代碼的情況下檢查代碼中的內容[3]。因此,進行抽象語法樹的提取不需要擁有完整、可運行的代碼,在僅僅存在部分軟件代碼時就可以進行抽象語法樹的提取。
ANTLR是一個開源語法分析生成器,其前身是PCCTS,它為包括Java、C++、C#在內的語言提供了一個通過語法描述來自動構造自定義語言的識別器、編譯器和解釋器的框架[4]。
以使用PMD工具提取Java代碼結構為例,所提取的抽象語法樹結構如圖 3所示。
圖3 抽象語法樹結構
軟件設計模型生成工具使用XML文件作為抽象語法樹的載體,將軟件代碼結構的相關信息保存在XML格式文件中,從而實現抽象語法樹的存儲,為后續(xù)的軟件代碼建構建模功能提供支撐。
通過建立軟件代碼結構設計模型,來實現抽象語法樹結構讀取和存儲,模型結構如圖4所示。
圖4 軟件代碼結構設計模型
AbstractXmlElement類為軟件代碼結構設計模型中所有模型元素的基類,用于存放所有模型元素所共有的公共屬性和方法。
ProjectElement類表示模型中的項目元素,用于存放項目的相關信息。它是軟件代碼結構的頂層節(jié)點,即所提取的抽象語法樹的根節(jié)點,通過該類可以獲取完整的抽象語法樹的相關信息。
PackageElement類表示模型中的包元素,用于存放包的相關信息。
ClassBaseElement類為所有接口和類的父類,由于接口和類具有諸多相似屬性和特征,因此通過設置相同的父類,來存放它們所共有的公共屬性和方法,如名稱、父類、注釋等信息。
InterfaceElment類表示模型中的接口元素,用于存放接口類的相關信息。
ClassElement類表示模型中的類元素,用于存放普通類的相關信息。
FieldElement類表示模型中的屬性元素,用于存放類的全局變量的相關信息。
MethodBaseElement類為所有構造函數和方法的父類,由于構造函數的本質也是方法,因此通過設置相同的父類,來存放它們所共有的公共屬性和方法,如名稱、參數列表、修飾符等信息。
ConstructorElement類表示模型中的構造函數元素,用于存放類的構造函數的相關信息。
MethodElement類表示模型中的方法元素,用于存放類的普通方法的相關信息。
其中,ProjectElement、PackageElement、Class-BaseElement、FieldElement、MethodBaseElement通過繼承AbstractXmlElement類獲得所有模型元素的公共屬性和方法。
InterfaceElment和ClassElement通過繼承Class-BaseElement類獲得所有模型元素以及類元素的公共屬性和方法。
ConstructorElement和MethodElement通過繼承MethodBaseElement類獲得所有模型元素以及方法元素的公共屬性和方法。
此外,上述模型元素之間還存在相互關聯關系。如:一個項目元素下包含一個或多個包元素;一個包元素下包含一個或多個接口元素或類元素;一個類元素下包含一個或多個屬性元素和方法元素等。
通過將抽象語法樹轉化為上述模型元素,并建立模型元素之間的邏輯關系,實現了軟件代碼結構建模,為生成軟件設計文檔提供依據。
各個類的含義及與抽象語法樹結構的對應關系如表1所示。
表1 設計模型類與抽象語法樹結構對應關系
本工具無需安裝,可直接打開使用本工具。由于軟件設計模型生成工具不提供用戶和權限控制,工具啟動后直接打開主界面,如圖5所示。
圖5 工具主界面
設置選擇項目、保存路徑、以及開發(fā)語言等項目信息后,可以通過“開始分析”按鈕執(zhí)行源代碼分析。
工具首先根據項目路徑獲取軟件代碼,根據所設置的開發(fā)語言,使用相應工具提取軟件代碼的抽象語法樹,再將抽象語法樹保存在“保存路徑”中的XML文件中,以便隨時獲取。最后讀取抽象語法樹的XML文檔,生成軟件代碼結構設計模型,并將其以樹型展示在左側,右側各個標簽頁用于顯示抽象語法樹上各節(jié)點的詳細信息。
所提取的抽象語法樹的部分XML文件如下:
默認顯示“包的一覽表”標簽頁,用于顯示源代碼中所包含的所有包的名稱、標識、層級編號及其簡要描述,如圖6所示。其中,層級編號、簡要描述列可進行修改編輯。
圖6 包的一覽表
工具從代碼結構設計模型的頂層包開始,采用深度優(yōu)先遍歷算法,逐層遞歸遍歷所有包,同時記錄遞歸層級作為包的層級編號。最后,將遍歷結果展示在“包的一覽表”列表中。
在“類的一覽表”標簽頁中顯示源代碼中所包含的所有類的名稱、標識、歸屬包標識、父類、層級編號及其實現功能,如圖 7所示。其中,層級編號、實現功能列可進行修改編輯。
圖7 類的一覽表
選擇抽象語法樹上包含子包的包節(jié)點,在“包的說明”標簽頁中顯示所選包節(jié)點中子包的名稱、標識、層級編號及其簡要描述。其中,層級編號、簡要描述列可進行修改編輯。在“包圖”標簽頁中顯示所選包節(jié)點的所有子包結構圖。
選擇抽象語法樹上不包含子包的包節(jié)點,在“類的說明”標簽頁中顯示所選包節(jié)點中所有類的類名、標識、實現功能。其中,實現功能列可進行修改編輯。在“包的類圖”標簽頁中顯示所選包節(jié)點的所有類的類圖。
選擇抽象語法樹上的類節(jié)點,在“類的詳細設計”標簽頁中顯示所選類的類名、標識、父類、說明,類中所有屬性的名稱、類型、說明,類中所有方法的函數名、參數、返回值、說明,如圖8所示。在“類圖”標簽頁中顯示所選類節(jié)點的類圖。
圖8 類的詳細設計
完成對源代碼分析結果的修改后,通過“導出設計文檔”按鈕,可以根據修改后的源代碼分析結果,生成軟件設計文檔,如圖9所示。
圖9 生成設計文檔
文中針對軟件設計文檔缺失或源代碼與設計脫節(jié)的問題,使用Java語言和Java Swing圖形界面工具,開發(fā)設計了一套基于源代碼的軟件設計模型生成工具。實現了從源代碼中逆向提取軟件設計模型,并生成與軟件代碼結構一致的軟件設計文檔。其對于提高軟件質量,完善軟件配套文檔,提高軟件開發(fā)效率均具有重要意義。