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