楊瀟
摘要:設(shè)計(jì)模式是面向?qū)ο蟮能浖_(kāi)發(fā)中一種可重用的、能夠解決軟件設(shè)計(jì)開(kāi)發(fā)中普遍存在問(wèn)題的方法。識(shí)別軟件系統(tǒng)中的設(shè)計(jì)模式能夠幫助相關(guān)開(kāi)發(fā)人員和維護(hù)人員更好的理解軟件系統(tǒng)的設(shè)計(jì)。尤其是GoF[1]中的結(jié)構(gòu)型設(shè)計(jì)模式,解決了如何組合類和對(duì)象獲得更大結(jié)構(gòu)的設(shè)計(jì)問(wèn)題。所以對(duì)于結(jié)構(gòu)型設(shè)計(jì)模式的識(shí)別能夠有效地提高軟件的理解和可維護(hù)性。在該論文中展示了是一種識(shí)別面向?qū)ο筌浖到y(tǒng)中設(shè)計(jì)模式的方法。該方法能夠自動(dòng)的識(shí)別出軟件系統(tǒng)中的結(jié)構(gòu)型設(shè)計(jì)模式。
關(guān)鍵詞:設(shè)計(jì)模式檢測(cè);源代碼分析;逆向工程
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2015)08-0236-04
Abstract: Design Patterns are reusable design elements in object-oriented software design and development. Design Patterns aim at providing solutions for recurring design problems in software development. Detecting design patterns in existing software systems can improve the comprehension of software systems. The structural design patterns mentioned in GoF Patterns[1] are concerned with how classes and objects are composed to form larger structures. Thus, detecting structural design patterns are extremely useful for software comprehension and maintenance. In this paper I present an approach to detect design patterns in object-oriented software systems. It is an approach for automatically detection of structural design patterns.
Key words: design pattern detection; source code analysis; reverse engineering
1 課題背景
對(duì)軟件系統(tǒng)的全面深入理解對(duì)于現(xiàn)代軟件工程的發(fā)展有著舉足輕重的作用。因?yàn)檐浖斫馐潜WC軟件有效維護(hù)和再工程的一個(gè)重要因素[2]。隨著軟件規(guī)模的日益增大,軟件理解的工作變得越發(fā)的重要。
如果軟件系統(tǒng)具有完整的文檔信息,那么想要全面理解一個(gè)已有系統(tǒng)也并非難事。但是,現(xiàn)實(shí)的狀況是在軟件開(kāi)發(fā)的過(guò)程中相關(guān)文檔缺失、不全面,或者文檔與系統(tǒng)不一致。這樣則給軟件理解造成了很大的阻礙。由此也導(dǎo)致了軟件維護(hù)和再工程的代價(jià)昂貴、需要耗費(fèi)大量的人力物力或者根本無(wú)法得以繼續(xù)。
由于設(shè)計(jì)模式中包含了解決一般常見(jiàn)設(shè)計(jì)問(wèn)題的通用解決方法,尤其是其中的結(jié)構(gòu)型設(shè)計(jì)模式,通過(guò)繼承機(jī)制或者對(duì)象組合的方式使得類和對(duì)象能夠相互組合并構(gòu)成更大的系統(tǒng)。所以提取結(jié)構(gòu)型設(shè)計(jì)模式的相關(guān)信息能夠幫助我們更加充分的理解系統(tǒng)。
2 識(shí)別過(guò)程
本論文中所研究的設(shè)計(jì)模式識(shí)別算法是基于抽象語(yǔ)法樹(shù)靜態(tài)分析的自動(dòng)化識(shí)別。其基本方法如圖1所示.
2.1 從源代碼生成抽象語(yǔ)法樹(shù)
本論文所提出的設(shè)計(jì)模式識(shí)別方法是基于源代碼靜態(tài)分析的。在本文的識(shí)別方法中,首先是根據(jù)源代碼構(gòu)建其抽象語(yǔ)法樹(shù)模型。通過(guò)抽象語(yǔ)法樹(shù)模型的建立,得到程序在更高抽象層面上的表示。再對(duì)抽象語(yǔ)法樹(shù)進(jìn)行分析,能夠有效簡(jiǎn)化源代碼分析的復(fù)雜度。抽象語(yǔ)法樹(shù)的生成,基于第三方開(kāi)源工具RECODER[3]來(lái)實(shí)現(xiàn)。
2.2分析抽象語(yǔ)法書(shū)得到設(shè)計(jì)模式候選實(shí)例
設(shè)計(jì)模式候選實(shí)例識(shí)別的過(guò)程,概括的說(shuō)即是分析設(shè)計(jì)模式類圖,分解類圖中各角色的相互關(guān)系;根據(jù)分解關(guān)系設(shè)計(jì)算法流程搜索程序的抽象語(yǔ)法樹(shù)模型,得到滿足關(guān)系的設(shè)計(jì)模式候選實(shí)例的過(guò)程。
在本論文中,采用元組的方式來(lái)描述一個(gè)設(shè)計(jì)模式實(shí)例,即對(duì)于任何一個(gè)設(shè)計(jì)模式實(shí)例,采用Design Pattern:(Role A, Role B, Role C)
的形式來(lái)表達(dá)。
而在分析和分解設(shè)計(jì)模式類圖各角色的相互關(guān)系時(shí),本文只關(guān)注一下三種類型的關(guān)系,即繼承、代理、組合關(guān)系。本文約定用這三種關(guān)系來(lái)表示一個(gè)設(shè)計(jì)模式所需要滿足必要條件,同時(shí)采用如下表達(dá)式來(lái)表示繼承、代理、組合關(guān)系:
1) 繼承關(guān)系:Inheritance(Super Class, Sub Class)
2) 代理關(guān)系:Delegation(Delegator, Delegatee)
3)組合關(guān)系:Composition(Container, Containee)
具體地,對(duì)抽象語(yǔ)法樹(shù)進(jìn)行分析識(shí)別設(shè)計(jì)模式候選實(shí)例的過(guò)程,可以分解為如圖2所示的三個(gè)步驟:
1)確定設(shè)計(jì)模式實(shí)例的元組表示
[1]中包含了所有結(jié)構(gòu)型模式的結(jié)構(gòu)圖。而確定設(shè)計(jì)模式元組表示的過(guò)程,即是將結(jié)構(gòu)圖中除Client之外的所有角色表示為一個(gè)N元組。
2)分析設(shè)計(jì)模式類圖并分解出各角色間的繼承、代理、組合關(guān)系
繼承關(guān)系和組合關(guān)系在UML類圖中是非常明顯的,可以直接找出。而代理關(guān)系則是通過(guò)兩點(diǎn)判斷:一、判斷在類圖中存在的依賴關(guān)系是否為代理關(guān)系,若是則直接找出;二、根據(jù)類圖所給注釋推斷出隱含的代理關(guān)系。
3)設(shè)計(jì)候選實(shí)例識(shí)別算法流程
模式候選實(shí)例算法的起點(diǎn)均為遍歷系統(tǒng)中所有的類。在遍歷的過(guò)程中,根據(jù)類、對(duì)象間的關(guān)系逐步找到滿足步驟2關(guān)系的元組。
在設(shè)計(jì)模式候選實(shí)例識(shí)別算法的設(shè)計(jì)過(guò)程中,需要遵循以下幾個(gè)原則:
①根據(jù)類的繼承層次自底向上分析
② 優(yōu)先獲取繼承相關(guān)類
2.3約束條件檢查
對(duì)已經(jīng)識(shí)別出的實(shí)例進(jìn)行進(jìn)一步檢查,以剔除其中不符合約束的實(shí)例。需要明確的一點(diǎn)是,候選實(shí)例識(shí)別的過(guò)程是從整個(gè)系統(tǒng)進(jìn)行搜索;而約束檢查則僅針對(duì)已經(jīng)識(shí)別出的候選實(shí)例。
約束條件的檢查過(guò)程如圖3所示。
1)候選實(shí)例角色完備性約束檢查
在文本所述設(shè)計(jì)模式候選實(shí)例的識(shí)別過(guò)程中,候選實(shí)例是根據(jù)類圖的分解關(guān)系搜索抽象語(yǔ)法樹(shù)模型得到的,可能會(huì)出現(xiàn)角色對(duì)應(yīng)類為空的情況。所以,我們需要檢查候選集中每個(gè)實(shí)例的角色完備性。
2)自身約束條件檢查
對(duì)抽象語(yǔ)法樹(shù)進(jìn)行分析得到候選實(shí)例的過(guò)程,是根據(jù)類與對(duì)象間的相互關(guān)系進(jìn)行信息提取、判斷而得到設(shè)計(jì)模式實(shí)例的過(guò)程。這個(gè)過(guò)程,主要關(guān)注的是類與類的相互關(guān)系 ,而忽略了類本身的一些屬性。所以為了增加識(shí)別的準(zhǔn)確性,我們還需要從類自身的一些屬性出發(fā)檢查。
自身約束條件主要考慮以下兩個(gè)方面:
① 訪問(wèn)權(quán)限修飾符
訪問(wèn)權(quán)限修飾符在編程語(yǔ)言中具體所指為public private protected 關(guān)鍵字。
在本文的方法中只檢查角色對(duì)應(yīng)類是否被public關(guān)鍵字所修飾,約定該約束使用表達(dá)式IsPublic( Class ) 表示一個(gè)類被public關(guān)鍵字修飾。
② 類類型
在本文中,類類型指的一個(gè)類(Class)是接口、抽象類還是具體類。
設(shè)計(jì)模式的類類型約束,可以直接通過(guò)設(shè)計(jì)模式類圖得出。
3)不存在關(guān)系檢查
候選實(shí)例的識(shí)別過(guò)程中,算法設(shè)計(jì)只考慮了設(shè)計(jì)模式中角色與角色之間的必要關(guān)系。除了存在的必要關(guān)系,在設(shè)計(jì)模式各角色間可能還有不存在關(guān)系。
同樣的,在不存在關(guān)系的檢查中,本文同樣也只針對(duì)繼承關(guān)系、代理關(guān)系和組合關(guān)系進(jìn)行檢查。
2.4 Adapter模式實(shí)例
本小節(jié)將以Adapter模式的識(shí)別過(guò)程為例具體闡述本文所論述的設(shè)計(jì)模式識(shí)別一般方法是如何變?yōu)榫唧w的識(shí)別流程的。
3 實(shí)驗(yàn)
對(duì)本文提出的方法,我們?cè)谝恍╅_(kāi)源項(xiàng)目中進(jìn)行了實(shí)驗(yàn)。在此,三種不同版本的JHotDraw項(xiàng)目(5.1, 6.0b1和7.0.6),和J2SE 5.0中的java.*包。
J2SE是Java 2標(biāo)準(zhǔn)版的縮寫(xiě)[4],其中包含構(gòu)成Java語(yǔ)言核心的類。JHotDraw是一個(gè)二維GUI繪制的Java框架[5]。
本實(shí)驗(yàn)環(huán)節(jié)中對(duì)Adapter, Composite和Decorator三種模式做了實(shí)驗(yàn),得到的結(jié)果如下:
4 結(jié)論與展望
本論文提出了一種結(jié)構(gòu)型設(shè)計(jì)模式的自動(dòng)化識(shí)別過(guò)程。旨在通過(guò)這樣的方式來(lái)更好的支持對(duì)軟件系統(tǒng)的理解。該方法首先將源代碼轉(zhuǎn)換成抽象語(yǔ)法樹(shù),并使用靜態(tài)分析的方法對(duì)其進(jìn)行分析以得到軟件系統(tǒng)中的設(shè)計(jì)模式實(shí)例。
同時(shí),本文使用提出的方法進(jìn)行了實(shí)驗(yàn),通過(guò)對(duì)實(shí)驗(yàn)環(huán)節(jié)得到的多組數(shù)據(jù)進(jìn)行分析,驗(yàn)證了本文所述算法的能夠較為有效的識(shí)別實(shí)際項(xiàng)目中存在的設(shè)計(jì)模式實(shí)例。
本論文雖然提出了一個(gè)通用的結(jié)構(gòu)型設(shè)計(jì)模式識(shí)別的通用算法設(shè)計(jì)原則和流程。但是對(duì)于每一種設(shè)計(jì)模式的具體設(shè)別過(guò)程,依舊需要具體模式具體分析。所以,在之后的研究中希望能夠進(jìn)一步增強(qiáng)算法的通用性,由此來(lái)提高該自動(dòng)化識(shí)別方法的可擴(kuò)展性。
參考文獻(xiàn):
[1] Gamma E,Helm R,Johnson R,et al.Design Patterns: Elements of Reusable Object-Oriented Software[M].Addison-Wesley,1995.
[2] Pacione M J,Roper M,Wood M.A novel software visualisation model to support software comprehension[C].Reverse Engineering Proceedings.11th Working Conference on,2004:70-79.
[3] RECODER Main Page[EB/OL].http://recoder.sf.net.
[4] J2SE 5 Source Code[EB/OL].http://www.oracle.com/technetwork/java/javase/downloads/index.html.
[5] JHotDraw Start Page[EB/OL].http://www.jhotdraw.org.