陳海燕 朱宇來 林陽 馬蕾 常瑩
摘 要:在計算機應用程序的開發過程中,軟件結構的前期設計對代碼實現和后期維護、擴展和升級等工作的影響重大,直接影響軟件的代碼編寫規模、可擴展性等。良好的結構設計能夠縮小軟件規模,提高代碼的復用率。其中,總線式結構設計是維持軟件可擴展性的一種方法。將軟件按功能設計為不同的模塊(插件),將這些模塊組合在一起,通過總線管理各個模塊協同工作。當軟件需要擴展時,加入新模塊或更新舊模塊就可以實現。該文講述的是基于總線式的結構設計方法,利用.NET框架中的反射(Reflection)機制對類型信息的描述能力,提出一種模塊組合結構的優化方法,用來增強軟件的可維護性,并保持對用戶自定義數據結構的處理能力。
關鍵詞:軟件開發 結構設計 模塊 總線 插件 優化 C# NET 反射
中圖分類號:TH703 文獻標識碼:A 文章編號:1672-3791(2014)10(a)-0021-02
計算機技術發展至今,程序結構設計思想已經逐步成熟。面向對象程序設計、模塊化設計等概念已經深入人心。應用程序的可維護性已經成為衡量軟件質量的重要標準。增強程序的可維護性可通過良好的結構設計、模塊化的功能區分等方法實現。結構設計越清晰,模塊間的耦合度越低、相關程度越小,程序的可拆分、可組件、可擴展的能力越強。總線—插件式的程序結構設計是提高軟件質量的重要方法。總線負責各個模塊的加載、事務的調度、資源的分配和消息的管理等。模塊(插件)是一種獨立的功能單元,完成總線安排的事務處理、數據轉換工作。這樣的方法避免了功能修改、擴展時,局部功能的改動需要修改大量與之相關的代碼,只需要改動模塊這個功能單元就可以實現了。這種程序設計方法就好比是PC機的硬件結構,主板是所有硬件的平臺,通過主板總線完成各硬件間的消息、數據傳遞,進行功能組合。若要升級計算機的性能,功能等,只需要升級個別部件,或插入特定功能的擴展硬件就可以了。
1 模塊獨立性
模塊的獨立性越強,其靈活程度越低。也就是說為了保證模塊的獨立性,必須不與其他模塊或類型產生依賴關系,函數的參數不能使用其他模塊中的定義類型。所以,使用通用性強的變量類型作為模塊的出入口參數能夠保證其較高的獨立性。但在以處理復雜數據結構為核心功能的大型應用程序(如地理信息系統、圖形處理系統等)中,每一個功能模塊都圍繞著復雜數據類型(空間數據、圖形數據等)進行設計。若將模塊中處理復雜數據類型的函數參數設計為自定義的復雜數據類型,必然產生對此種數據結構的依賴,模塊獨立性大幅下降。若將參數設計為簡單變量,則失去了定義這個復雜數據類型的初衷,可理解性變差,反而使程序開發變得復雜。若將此數據類型作為公用類型,讓所有模塊都可訪問,雖然既保證了函數參數的通用性,也方便了數據處理,但必然會受到這個公用數據類型的限制,這個數據類型的改動將涉及所有模塊的代碼重寫,直接降低了程序的可擴展性能。
2 結構優化原則
該文探討一種模塊的優化組合方法,在面對復雜數據結構的情況下,能夠提高模塊的獨立性。這種方法以總線式結構為基礎,利用Microsoft.NET Framework的反射機制作,管理模塊加載和配置,達到程序的深層次修改和模塊多維擴展的目標。此方法遵循的原則是:(1)靈活的模塊組合方式。模塊組合的方法操作簡單,結構靈活,方式多樣,加載的方式必須一致。不僅要求模塊可替換、可擴展,還能實現新老版本模塊的交替使用。(2)明確的模塊間相互依賴關系。所有模塊不能依賴于下層模塊里的類、屬性、字段、方法等,只能依賴上層模塊。所有模塊之間的關聯,必須是松耦合關聯,并且關聯方式必須通過頂層模塊調用。(3)簡潔的接口設計。簡化總線和固定模塊的功能,減小接口的數量和規模,強化組件、工具的功能,工具的使用必須采用一致的接口調用。
3 程序結構設計優化
根據軟件的業務邏輯模型,將模塊各部件封裝成類,變為獨立的整體單元,自上而下的將模塊組合設計為層次結構,可用樹形結構描述。樹形結構的根節點位置模塊,就是系統總線。總線并不負責所有子模塊的加載,子模塊的加載工作交給另一個中間件完成。總線只是一個容器,提供所有模塊的存儲空間和總線資源的引用方法。將總線也設計為模塊,若系統功能改變,總線也可以像其他子模塊一樣,進行替換。模塊加載中間件邏輯上位于兩個模塊中間,實現宿主模塊和多個子模塊關聯。它為宿主模塊提供子模塊的加載方法,并規范子模塊,使之符合被載入條件。為了敘述方便,將這個中間件命名為ModuleLoader,它繼承于被命名為IBus的資源調用接口,讓被載入子模塊通過接口能夠向上搜索,找到樹形結構的根節點—總線,子模塊通過總線調用其模塊的各種功能。ModuleLoader的核心部件是其內部維護了一個可加載類型的配置列表,當向模塊中插入下級模塊時,只需要向此表中添加一個類型,由ModuleLoader自動完成對這個類型的所有繼承類型的掃描,并選擇符合條件的加載類型,進行實例化。軟件框架搭建時,讓所有可擴展的模塊基類都繼承于ModuleLoader類型,模塊的擴展采用繼承的方法。這樣,所有的模塊都具備載入其它模塊和被載入的功能,并且載入的模塊可以被選擇和配置。開發者可以實現任意兩個模塊之間的從屬結構關聯,從而構成復雜的程序框架結構。
4 ModuleLoader的設計
ModuleLoader的關鍵功能是實現模塊的動態加載。其原理是它實現了對模塊子類的掃描功能,這種掃描功能利用了.NET Framework提供的反射機制(Reflection),該項可以在運行時獲得.NET中每一個類型(包括類、結構、委托、接口和枚舉等)的成員,包括方法、屬性、事件,以及構造函數等。樹形結構中的每個ModuleLoader中都內含擴展類型配置集,利用反射的功能,掃描配置集中類型的子類信息,檢查配置狀態,當條件符合時,創建這個類型的實現,加入到實例列表中。當需要擴展一個模塊時,只需要修改其宿主模塊的配置集信息,ModuleLoader會自動搜索到這個類,實例化該類型,替換原有模塊。ModuleLoader由兩部分組成:(1)配置工具部分包括:用于存儲所有的可擴展類型和狀態的集合、用于獲取模塊子類信息的掃描工具、用于自動創建配置集信息的構造器和用于配置集信息設計和獲取的配置器。(2)實例化工具部分包括:用于保存所有子模塊實例的對象列表、用于根據配置集信息創建模塊實例的構造工具、用于增加、刪除、替換模塊實例的管理工具和用于獲取用戶所需子模塊實例的對象提取工具。這兩大部分協同操作,使ModuleLoader不僅可以加載、管理不同類型的多種模塊,也可實現對模塊不同版本的交替使用,使程序框架中模塊的組合方式更加靈活。
5 命名空間的依賴性
為了提高模塊的獨立性,消除模塊間的病態關聯,必須明確規范模塊間的相互依賴關系。利用命名空間的可視范圍來限制模塊間相互依賴的規范方法是可取的。因為下層命名空間的對象可以訪問上層命名空間的類型,而上層命名空間的對象是無法訪問到下層以及同層其他命名空間的對象資源的。根據軟件結構的邏輯關系,確定命名空間的層次,順序,范圍。當結構下層的模塊使用另一個命名空間的模塊時,必須通過ModuleLoader訪問頂層的IBus接口調用其它模塊對象。并且規定不準使用對下層或同層其他命名空間的直接引用。這樣的規范方法,能夠保證所有調用都通過頂層總線,避免了模塊之間的非邏輯性關聯,在一定程序上提高了模塊的獨立性。
6 接口設計
若說命名空間為模塊之間的訪問設置了阻礙,則接口設計就是在不可視的模塊之間搭建了相互使用的橋梁,讓其間產生了相互使用的可能。所以模塊的接口應位于命名空間的較高層次,確保特定功能范圍內的可視性。接口一旦定義,一般不輕易修改。因此,為通用性高的核心固定模塊設計接口,將使用率低,通用性不高的功能設計為工具,所有工具只設計一種接口的方法較為合理。工具集內部也可以按功能設計為層次關系,并用動態加載的方式進行管理。但工具的使用必須采用統一的接口調用方法。這樣的設計能夠減少接口的數量,控制固定接口的規模,減少接口擴展時的代碼編寫工作量,從而達到優化程序結構的目的。
7 數據結構調用
數據結構是決定模塊獨立性的重要關鍵問題。在專業軟件中,多種基本數據類型聚合為復雜的數據類型,這種復雜數據類型符合軟件業務功能的邏輯模型,能夠便于被各模塊分析、處理。但是數據類型一經定義,很難擴展。當大量模塊都使用此種數據類型時,增加、改變其中的一個變量的名稱就可能涉及大量模塊的改動。所以數據類型經邏輯分析組裝好后,也可為其設計接口,模塊通過接口調用復雜數據類型的對象。只要接口不改變,即使數據類型變化,所有的模塊還能通接口調用的方式,對數據類型繼承訪問。但使用這種方法時要注意兩個問題:(1)若在子模塊中創建復雜數據類型的實例時,應利用ModuleLoader提供的方法動態創建數據類型的實例,并轉換為接口類型使用。(2)接口中可能會變化的屬性,最好使用泛型集合類型定義。模糊化了的屬性類型,能夠保證數據類型的擴展,不會某些固定類型的限制,否則也不會達到數據類型可擴展的目的。
8 效率分析
由于對象的多層次引用和動態創建,配置集的頻繁搜索,大量的封箱、拆箱操作等,必然會犧牲軟件運行的時間和空間效率。但用這種犧牲換取的是良好的模塊封閉性和結構的緊湊性。而且,由于復雜的動態管理功能被封裝在ModuleLoader里,所以在開發、使用層次的實際操作變得十分簡單,犧牲運行效率的過程一般發生在初始化環境、事務高度和模塊運行的起始環節,在飛速更新的計算機硬件上已經顯得微不足道。實際上,工程師更關心軟件的結構、擴展性和局部操作性能(如空間數據的顯示、處理效率),只有對局部模塊內部的功能不斷優化、升級、擴展,才能真正提高軟件的運行效率,而這樣的優化和升級必須建立在良好的結構基礎之上的。
9 結語
開放的結構、靈活的擴展方式、彈性的組合方法讓軟件框架結構的組織變得更加清晰、緊湊,延長了軟件的生命周期。結構設計讓程序開發工作能夠產生良性的優化機制,讓開發者能夠始終站在巨人的肩膀上,精益求精,不斷創造奇跡,讓工程師有精力將注意力由開發技術研究轉化為開發工藝研究。云計算的時代即將到來,優化模塊結構不僅適用于桌面應用程序,也適用于云端服務單元的創建,在“軟件—服務”這一思潮涌來之時也將大有作為。
參考文獻
[1] 馬蕾.基于改進身份認證協議的單點登錄系統研究[J].微電子學馬計算機,2010,29(7):180-183.