本文首先介紹了遺留代碼的概念,並對遺留代碼進行了分類。針對不同類型的遺留代碼,提供了相應的處理策略。此外,本文重點介紹了Qoder CN在維護遺留代碼過程中能提供哪些支援。
Qoder CN 系列全新文檔網站現已上線。當前網站的文檔內容可能無法反映產品的最新功能與變化,請訪問 docs.qoder.cn 擷取最新產品文檔。
什麼是遺留代碼
-
與過時技術相關的代碼:
-
與不再受支援的作業系統或軟體庫相關的代碼。
-
依賴於已淘汰的技術棧或程式設計語言的代碼。
-
-
為相容老舊功能而保留的代碼:
-
在現代軟體中為了相容舊版本功能而保留的程式碼片段。
-
為了確保向後相容性而不得不保留的代碼。
-
-
缺乏文檔和維護的代碼:
-
沒有良好文檔支援的舊代碼。
-
缺乏現代開發實踐(如單元測試、代碼審查等)的代碼。
-
解決遺留代碼的方法
解決遺留代碼有以下三種常見的處理方法:
|
處理方式 |
利弊 |
|
推翻重來 |
成本高,系統正在運行,會帶來代碼風險。 |
|
進行重構 |
|
|
補充單元測試 |
通過單元測試識別現有代碼中的問題,為未來可能的代碼變更提供品質保障。 |
根據上述描述,補充單元測試是一種有效解決遺留代碼問題的方法。然而,這種方法仍然存在一些問題:
-
大量遺留代碼缺少單元測試,並且由於代碼間的複雜依賴關係,進行測試的成本非常高。
-
具體的衡量標準卻不夠清晰,無法定義好的單元測試。
-
哪些代碼需要添加單元測試?
單元測試常見的誤區
-
缺乏斷言的假單元測試:開發人員可能會採取僅調用函數而不進行斷言的方式,以提高覆蓋率指標,導致了許多無效的單元測試。
-
把單元測試當成白盒測試:一些觀點將單元測試歸類為白盒測試,但實際上應將其視為針對函數簽名的黑箱測試。
-
依賴真實環境的單元測試:阻礙單元測試的主要因素包括惰性和依賴環境配置。若不使用Stub或Mock解除對外部環境(如網路IP、資料庫)的依賴,單元測試將難以達到FIRST原則(快速、獨立、可重複、自我驗證、及時性)。
選擇性的進行單元測試
單元測試除了帶來收益外,本身也會產生一定的成本。如果從收益與成本的角度分析遺留代碼,將有助於明確為遺留代碼補充單元測試的策略,此策略被稱為選擇性單元測試。那麼,如何界定成本與收益呢?
遺留代碼單元測試的成本收益象限分類
針對遺留代碼的單元測試,可以根據其成本和收益進行象限分類。根據下圖,對分類標準和各象限進行詳細說明:

分類標準
-
X軸(成本):代碼依賴程度越高,測試成本越大。
-
Y軸(收益):代碼複雜度越高,品質收益越大。
四個象限
|
代碼分類 |
特性 |
描述 |
收益 |
成本 |
|
演算法類代碼(Algorithms Code) |
循環複雜度高,扇入大。 |
包含較多條件判斷和迴圈語句,依賴其他代碼少,但被大量代碼依賴。 |
高 |
低 |
|
瑣碎代碼 (Trivial Code) |
循環複雜度小,扇入大。 |
通常是一些簡單的方法,只有一兩行代碼。 |
低 |
低 |
|
協調類代碼(Coordinators Code) |
循環複雜度小,扇出大。 |
處於調用關係的上層,通過調用其他代碼來反映特定業務情境。 |
低 |
高 |
|
複雜代碼(Overcomplicated Code) |
循環複雜度大,扇出大。 |
邏輯複雜,依賴多,函數冗長且參數繁多,是典型的代碼異味。 |
高 |
高 |
循環複雜度與依賴的概念理解
-
循環複雜度(Cyclomatic Complexity):衡量代碼中邏輯分支的數量。
-
扇入(Fan-In):直接調用該模組的上級模組的個數,扇入大表示模組的複用程度高。
-
扇出(Fan-out):一個模組直接調用的其他模組的數量,扇出大表示該模組依賴其他模組越多。
不同類型代碼的處理策略
根據上述的分析,遺留代碼的處理策略就變得十分明確:
-
演算法類代碼(Algorithms Code):產生單元測試。
-
協調類代碼(Coordinators Code):進行介面測試。
-
複雜代碼(Overcomplicated Code):尋找合適的機會進行重構。
-
瑣碎代碼(Trivial Code):不做處理。

使用Qoder CN處理遺留代碼
1. 瞭解專案工程
在維護一個工程的遺留代碼,首先可通過 @workspace 功能瞭解整個工程的目的及其涉及的各個模組。

2. 對不同類型代碼進行處理
針對演算法類(Algorithms)代碼產生單元測試
選中需要基於生產代碼進行代碼產生的部分。在產生時,請注意所需的架構及Mock等依賴資訊,可以通過產生單元測試命令後追加相關資訊進行補充。如 /generate unit testingCppUTest。

一般而言,基於現有代碼產生的單元測試用例數量通常較為有限。如果對單元測試的測試情境及用例數量有具體要求,可以在新產生的單元測試檔案中,通過測試函數的續寫方式產生更多的單元測試。在續寫過程中,Qoder CN將儘可能遵循已有用例,以此作為上下文進行參考。

針對協調類代碼(Coordinators)進行介面測試
對於協調類代碼而言,單元測試並不是一種理想的解決方案,由於存在過多的依賴,測試成本顯著提高。針對此類代碼,應該採用介面測試或功能測試的方式進行覆蓋,然而在編寫自動化測試案例時,開發人員常常會遇到相關問題。因此,可以通過Qoder CN,快速掌握並理解測試架構。

針對用例的編寫,可以選擇相應的被測函數,並在問答區中直接提問:基於Robot Framework產生以下代碼的測試案例。沿著這一思路,同樣可以實現相應的Keywords等內容。
超複雜的代碼(Overcomplicated Code)找機會進行重構
針對超複雜的代碼,可以使用Qoder CN的 /generate optimization 命令,以獲得針對所選代碼的最佳化建議。代碼審查與最佳化將從文法問題、異常改進、代碼整潔度、安全性及風險等多個維度給出相應的最佳化建議。

針對複雜遺留代碼的最佳化,並不建議開發人員們盲目進行全面的最佳化和重構。遺留代碼的變更可能會帶來巨大的風險。因此,開發人員應根據具體情況,在合適的機會,遵守童子軍法則,進行重構和最佳化。在這一過程中,Qoder CN也將為您提供有力支援。
結語
以上便是在處理遺留代碼時可參考的實踐。處理遺留代碼需要深入代碼的複雜結構,細緻地追蹤每一個可能的分支節點。在這一過程中,除了識別並修複潛在的缺陷外,還必須在有限的時間內完成所有任務。為了避免這一局面的發生,最佳的策略是預防代碼的腐化,善用工具,並在編寫初期遵循良好的編程原則。