1 什么是遺留代碼
本質是一種技術債務,產生原因一方面是業務原因:如業務本身場景繁多、流程復雜等;另一方面是技術原因:如代碼不規范、設計不合理、祖傳代碼文檔注釋缺失等。它會影響我們的程序很多方面:如可讀性、可修改性、可復用性、可維護性、可測試性等。
2 遺留代碼處理過程拆解
劃分為梳理 -> 重構 / 重寫 -> 替換 / 驗證三個階段
2.1 梳理
遺留代碼的處理是一種逆向工程,從已有的代碼 + 數據模型 + 文檔倒推出業務模型、交互和規則,在保真的前提下再重新構建代碼 + 數據模型 + 文檔。
我們這里可以參考下 DDD 領域驅動設計里戰略設計部分常用的工具(事件風暴法)來進行這部分梳理工作。
事件風暴本質上是一種系統建模的方法,與它處于對等位置的,會有 “UML 建模”、“事件驅動建模” 等。事件風暴跟敏捷開發里的一些理念(如用戶故事)的產生背景類似,都是在理性思考無法應對變化頻繁且文字難以描述的情況下,通過一些輔助性的提示卡片、視覺手段,輔以相關人員的集中、高頻溝通來完成對于業務的準確把握和抽象建模。 事件風暴的過程:
通過梳理業務流程,創建相應的領域事件(Event)
補充引發每個領域事件的命令(Command)
通過實體 / 聚合把命令和事件關聯起來
劃分領域邊界及事件流動線條
識別用戶操作所需的關聯視圖及其角色
事件風暴的產物:
領域對象 即實體 / 聚合。這里的領域對象并非數據庫模型, 而是與業務緊密聯系的 “對象”。因為事件風暴是一種面向對象的建模方式, 而不是面向數據庫的建模方式。
領域事件 即對象在某些操作或特點時點下所產生的事件, 這些事件將決定之后多個聚合和限界上下文(BC)之間的通訊方式。
限界上下文 當所有的對象(實體 / 聚合)被梳理出來后,屬于同一種 “通用語言” 的對象, 則會被歸入同一個限界上下文邊界內;不屬于同一種 “通用語言” 的對象, 則會被邊界給分割開,劃入不同的子域或限界上下文。
梳理結果示例:
2.2 重構 / 重寫
通過重構 / 重寫對軟件要素進行重新組織,使其不改變外部行為的情況下,提升代碼的可讀性或使其結構更合理。
針對不同層次的軟件要素要做不同的處理和控制:
并且整個重構 / 重寫過程有些需要遵照的原則:
單一職責:可以將依賴歸攏,統一行為和控制。權責明確,場景明確。
單一原則:消除重復的數據聲明、行為;因為單一所以保證了復用,統一標準 ,可裝配性。
封裝原則:不需要過度關心依賴類內部實現,最好一個。就能調用。
歸屬原則:上帝的歸上帝,凱撒的歸凱撒。誰提供的數據更多,歸屬于誰。
抽象層次:越高層的抽象越穩定,越細節的東西越容易變化。舉例:接口應傳遞職責而非實現細節。
開閉原則:對修改關閉,對擴展開放。
kiss 原則:好理解,好維護。
清晰原則:只讀小部分代碼就可以知道怎么改邏輯,做擴展。而不是要通讀所有代碼,才能理清。
其中有兩點落地細節我們具體分析下:
業務邏輯的處理
業務代碼和技術代碼解耦
主流程代碼和附加流程代碼解耦
長鏈路的拆解編排
關注點的分離
雙向依賴:上下文之間缺少一層未被澄清的上下文,或者兩個上下文其實可被合為一個;
循環依賴:任何一個上下文發生變更,依賴鏈條上的上下文均需要改變;
過深的依賴:自身依賴的信息不能直接從依賴者獲取到,需要通過依賴者從其依賴的上下文獲取并傳遞,依賴鏈路過長,依賴鏈條上的任何一個上下文發生變更,其鏈條后的任何一個上下文均可能需要改變;
2.3 替換驗證
大概分為以下幾個要點:
領會意圖,抽取用例,增加可復測性
增加可監測性
分成小塊,逐步替換
試點、看到成效
可借助過程管理工具如 PDCA 法進行管理
3 案例演示
3.1 案例 1:針對強耦合的實現做重構
原始需求:案例為一個轉賬服務,用戶可以通過銀行網頁轉賬給另一個賬號,支持跨幣種轉賬。同時因為監管和對賬需求,需要記錄本次轉賬活動。 原始架構:是一個傳統的三層分層結構:UI 層、業務層、和基礎設施層。上層對于下層有直接的依賴關系,導致耦合度過高。在業務層中對于下層的基礎設施有強依賴,耦合度高。我們需要對這張圖上的每個節點做抽象和整理,來降低對外部依賴的耦合度。
重構關鍵設計點:
重構后代碼特征: 業務邏輯清晰,數據存儲和業務邏輯完全分隔。
Entity、Domain Primitive、Domain Service 都是獨立的對象,沒有任何外部依賴,但是卻包含了所有核心業務邏輯,可以單獨完整測試。
原有的轉賬服務不再包括任何計算邏輯,僅僅作為組件編排,所有邏輯均 delegate 到其他組件。
3.2 案例 2:提高老代碼的復用性
原始需求:現有幾個策略實現類,被很多代碼使用。現在需要根據不同的業務方在每個策略執行前做不同的前置邏輯處理。 解法分析:盡量避免把邏輯耦合到已有的實現類中。引入外部類進行控制反轉。這里我們使用訪問者模式。 訪問者模式把數據結構和作用于結構上的操作解耦合,使得操作集合可相對自由地演化。
訪問者模式適用于數據結構相對穩定算法又易變化的系統。因為訪問者模式使得算法操作增加變得容易。若系統數據結構對象易于變化,經常有新的數據對象增加進來,則不適合使用訪問者模式。訪問者模式的優點是增加操作很容易,因為增加操作意味著增加新的訪問者。訪問者模式將有關行為集中到一個訪問者對象中,其改變不影響系統數據結構。其缺點就是增加新的數據結構很困難。
具體實現:
重構后代碼特征: 可以通過訪問者對老代碼邏輯進行編排,將修改外置,減少對老邏輯的影響。通過 java8 默認接口實現提供默認訪問行為,避免大量策略子類的感知,只需要需要提供自己實現行為的子類對默認實現進行覆寫。
4 總結
遺留代碼的處理能力一方面是對技術的要求,另一方面也是對業務掌握的挑戰。希望我們可以跨越荊棘、穿過迷霧,順利到達成功的彼岸!
審核編輯:劉清
-
UML
+關注
關注
0文章
122瀏覽量
30850 -
JAVA語言
+關注
關注
0文章
138瀏覽量
20076 -
PDCA
+關注
關注
0文章
15瀏覽量
3079
原文標題:遺留代碼處理技巧與案例演示
文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論