陳武,汪驥宇,程植
(1.核動力運行研究所,湖北 武漢 430223;2.中核武漢核電運行技術股份有限公司,湖北 武漢 430223)
數字經濟時代的到來,軟件產業蓬勃發展,行業產值發展迅速,對軟件工程師的需求日益增加。軟件工程技術、軟件框架理論實踐不斷發展,各種開發框架理論和組件的出現,在軟件研發的各個領域,產生了巨大的作用,極大促進了軟件研發效率。這些框架的應用,能夠降低對軟件研發人員的知識儲備要求,降低了軟件研發工作的進入門檻。
微服務架構隨著云計算的興起,已經成為企業應用中的主流技術。在微服務架構應用中,廣泛地應用了各種開發框架、組件,其主要應用于SaaS 層應用的開發。Spring Cloud、MyBatis 框架組件是在微服務應用開發中,使用最為廣泛的框架。
這些開發框架帶來極大便利,同時也產生了許多新的問題。特別是在大型軟件項目中,對軟件質量管理的能力要求高,特別是在工期、資源緊張的情況下,代碼規范性執行力下降,導致軟件代碼的價值繼承性、可維護性降低。另外,在后期軟件新功能開發、系統功能維護過程中,也會進一步加劇這些問題。
研究這些問題解決方法具有很高的工程實踐意義,通過對軟件代碼的重構[1],解決或有效緩解這些問題,能夠極大提高軟件質量。軟件重構[2]理論有許多的模式,判斷如何使用、何時使用的問題,需要設計人員和開發人員的有很高的要求,在工程實踐中希望有一個有效的、易操作的方法指導軟件重構工作。
本文通過對某核電軟件研制工程項目中近百個采用了這兩個架構的微服務項目研究、分析,總結出在軟件研發過程經常發生幾個典型問題,提出微服務項目5分離法迭代重構模式,指導微服務項目進行重構,提高軟件的質量。
在某核電軟件研制工程項目中的微服務工程,在微服務設計中采用了領域驅動設計,以及典型的4層微服務架構如圖 1所示。架構模型中包括接口層、應用層、領域層、持久層,另外還有一個貫穿四層的基礎設施層。
1) 接口層:提供前端適配,實現針對不同的前端應用請求提供服務,實現對象轉換,以及數據組裝等場景。防止核心業務邏輯暴露、數據外泄,同時保證下層的穩定。
2) 應用層:提供應用服務,鏈接接口層和領域層,主要實現服務協同聚合、服務編排、服務組合,以及安全校驗等邏輯處理。
3) 領域層:提供核心業務服務,通過各種領域對象構建領域模型,各種對象的方法調用實現業務邏輯,對應用層提供服務。另外調用持久層服務,實現業務對象持久化。
4) 持久層:提供數據持久化服務,將數據存儲到數據庫中。
5) 基礎設施層:提供基礎公共服務,主要包括配置類、工具類、基礎公共模塊、其他公共模塊。
這種分層架構是一個弱耦合架構,層與層之間向下依賴,下層對上層無依賴,基礎設施其他層無依賴。這樣的分層架構帶來很多好處,如開發人員可以只關注整個結構中的其中某一層;可以很容易地用新的實現來替換原有層次的實現;可以降低層與層之間的依賴;有利于標準化;利于各層邏輯的復用[3]。

圖1 4層架構
在軟件研發項目中,依據范圍、進度、成本等方面要求,需要先選擇微服務工程進行重構任務的驅動。另外,軟件重構管理是一個持續的工作,作為以下重要的任務進行跟蹤。每個迭代中會進行重構任務分析,確定是否進行重構,對哪一個項目進行重構,重構的目標是什么。本節介紹一個在工程實踐中使用的簡易工程選擇模型,可以初步確定本迭代需要的微服務工程。在該模型中,涉及7 個元素,包括工程規模(代碼量)、人員更替次數、迭代次數、測試Bug 數、工程重要程度、重構次數。
如表1 所示,列出在本項目過程中某個迭代的分析結果。

表1 項目代碼分析表
根據情況選擇重構緊迫度排名以及項目組開發進度,選擇緊迫度高的項進行重構分析。在分析過程中,一般關注重要、核心業務相關實現代碼。
通過對微服務項目中重構實施的總結,得到5 個典型問題:超大類、規則劃分混亂、參數傳遞對象未區分、邏輯分層不清晰、業務規則重復。
隨著功能、業務規則不斷增加,業務類包括的功能越來越大,主業務類的邏輯非常復雜、龐大,導致超大類的出現。類太大會引發的問題一系列問題,如維護困難、規則修改困難,影響虛擬機運行,會導致內存頻繁地被占用和回收,類加載會消耗更多時間,占用更大內存,容易引起內存回收。
在開發過程中,隨著功能的迭代、邏輯的增加,會增加新的實體對象、事件對象、服務對象,來實現新的業務規則,也可能在原來的類中增加方法來實現新的規則。在這個過程沒有對模型進行重構,導致規則的歸屬出現混亂。
在4層模型中,前端展示層和接口層通過視圖對象(VO) 對象傳遞數據,接口層將對象轉換為數據傳輸對象(DTO) 傳遞給應用層,再轉換為領域對象(DO) 傳遞給領域層,最后通過持久化對象(PO) 傳遞給持久層進行持久化。
最常見的問題是一個對象穿透4層,容易導致業務邏輯的失控、信息安全失控、靈活性丟失等問題。
邏輯分層不清晰,在開發過程,未遵照分層的模型,將相應的業務邏輯在對應的層中實現。最常見的是在應用層的類方法中,實現領域模型的業務規則,這樣導致在其他應用服務需要相同的領域服務時,需要重寫一遍相關的規則代碼,導致模型的失控。為后續維護、新功能開發埋下隱患。
業務規則重復,在開發、運維過程中,采用敏捷開發的過程中,每一個開發人員會去寫自己的業務邏輯,往往一個業務規則會在不同的方法、不同的類中實現。另外在運維過程中,一個功能在開發過程、運維過程中的人員變化,導致問題修復功能優化時,往往采用復制的方法開發新的方法。
本重構模式包括重構流程和設計模式兩個方面的內容。重構流程定義了重構工作的工作流程,設計模式定義的重構的設計方法。
一項工作完美執行需要有一個有效的工作組織管理過程,在重構中按照圖 2 所示的流程組織,有效地進行服務項目的重構工作。包括模型回顧、關鍵方法分析、調用鏈分析、重構、測試5個環節。

圖2 重構流程
1) 模型回顧,重構開始時,需要對服務的模型進行完整的梳理,出現需要重構的情形往往伴隨著模型的滯后。這需要重新梳理,完善模型,做好重構準備。同時還需要做好確定本重構的目標,確定迭代的計劃。
2) 關鍵方法分析,在本步驟中對需要重構的內容進行分析,確定服務、對象的關鍵方法,需要重構的方法。
3) 調用鏈分析,確定需要重構的方法后,需要分析重構方法的調用鏈,識別使用情況,從而進步與確定該方法涉及的相關功能以及相關測試用例。
4) 重構,依照本文提到的重構設計模式,完成模型重構設計。然后進行代碼的開發,最終實現代碼的重構。
5) 測試,本步驟是需要依據前面步驟分析出的相關測試用例進行測試,從而驗證重構工作是否成功。
為解決本文中提到的問題,設計如圖3 所示的微服務5分離迭代重構模式,在該模式中采用多次迭代,5方法循環應用。在重構過程中,根據實際情況,通過分步迭代的方式,達到最終的重構目標。5 方法包括類分離、方法分離、數據分離、規則分離、代碼分離5種方法,這五種方法互為補充,靈活應用。

圖3 微服務5分離迭代重構模式
1) 類分離
《公務員法》規定公務員的薪酬由基本工資、補貼、津貼和獎金組成,并不包含福利和保險,但是,隨著社會的發展,福利在總薪酬中占比例越來越大,現代薪酬理論普遍接受全面薪酬或者總薪酬的概念,認為薪酬應該是包括基本薪酬、可變薪酬、福利和服務以及一次性獎金、股票期權等多種經濟型報酬。
對超大類首先采用類分解的方法,進行拆分,可以參考所示的模式進行分解。可以按照對象基礎類、查詢類、高級查詢類、添加類、修改類、校驗類、審批類,以及其他類等模式進行分解。最終形成一個對象類族。一般實施步驟如下:
①進行分類,將方法進行分類,然后根據分類創建類。
②然后將各種方法遷移到各自的類中。調整模型內部的代碼結構,修復方法遷移導致的相互引用的失敗錯誤。
③再修復上層調用中因為方法遷移導致的錯誤。
④最后進行服務測試。
2) 方法分離
如果業務方法實現過程中,出現規則劃分混亂的問題時,需要通過方法轉移的方式來糾正該問題,從而理順模型的規范性。一般做法如下:
②測試修改后的功能。
3) 數據分離
當發生傳遞參數對象未區分問題時,需要通過數據類型分解的方式,來處理該問題。一般做法如下:
①確定需要修改的相關業務服務,分析VO 和DO,確定雙方的差異。
②重新構造VO,構造數據類型轉換類方法。
③修改接口層、服務層接入數據對象,增加數據轉換方法調用。
④進行功能測試。
4) 規則分離
當發生邏輯分層不清晰問題時,需要進行重構,厘清規則的分層。一般做法如下:
①理清應用層邏輯中屬于領域部分的規則代碼。
②將該部分代碼抽取出,封裝到獨立的方法中。
③將該方法轉移到領域模型對應的類中。
④測試修改后的功能。
5) 代碼分離
如果存在較多的重復代碼塊,引發了業務規則重復的問題,如兩次以上超過10行的重復代碼,可以通過采用重復代碼抽取的方式。將重復的代碼抽取到公共的方法中,減少重復率,提供代碼的可讀性、可維護性。一般做法如下:
①同一個類型中的重復代碼抽象到公共的私有方法,將業務規則抽象封裝。
②如果該方法在同一個對象族中的其他類中也用到相同的規則,那么將這幾個類中的共同方法,根據方法的作用,轉移到相關的類型中。如公共校驗方法轉移到校驗類中,公共賦值方法轉移到基礎類或賦值類中。
③如果業務對象的類中使用到相同的規則,那么將這個共同規則方法,轉移到領域基礎類中。
④修改相關調用規則的代碼為調用公共方法。
⑤最后進行服務測試。
在面向對象、領域驅動設計[4]的理論中,以及典型設計模式理論[5]中,各種對象有明確的邏輯職責劃分,各層也有相應的劃分,數據的傳遞也有理論要求。軟件重構意味著需要更多的投入,在工程實踐中,往往并不能按照這些要求來判定是否需要重構。設計人員、開發人員還需要依據項目的實際情況,考慮業務的復雜度、重要度、使用情況等因素,確定是否重構。
本文中總結的問題,在很多工程中都存在,一般是隨著項目推進,工程規模不斷增大,這些問題才會顯現出來。對于一個規模小的項目,即使出現這些問題,對業務實現并沒有影響,對軟件質量也影響較小,不需要啟動重構的。
開發框架的使用,能夠極大地提高開發效率、降低開發人員要求,快速交付,從而能夠以較小的成本較短的周期完成項目。設計人員、開發人員在研發過程中需要不斷對代碼進行檢查,適時啟動代碼重構優化,從而提高軟件質量。本文的模式可以對這個過程提供一定的指導。