發(fā)布于:2021-01-27 11:21:22
0
80
0
在處理遺留代碼時(shí),我經(jīng)常遇到這樣的問題:必須重構(gòu)包含靜態(tài)方法或完全是靜態(tài)方法的類。
我之前談到過重構(gòu)助手類,但這有點(diǎn)不同。
在本例中,我想討論重構(gòu)類,您希望保留這些類,但這些類具有所有或多個(gè)靜態(tài)成員。
這種類是否真的是某個(gè)助手類并不總是很清楚,這是一個(gè)判斷調(diào)用,但是如果你真的找到了助手類,不要把它放在那里。
所以,基本上,如果你已經(jīng)確定你正在使用的類將繼續(xù)存在,但是它確實(shí)有靜態(tài)方法,你需要擺脫它們,因?yàn)槟阏谶M(jìn)行依賴注入或模擬,請(qǐng)繼續(xù)閱讀。
定義兩種方法
我說的分步重構(gòu)是什么意思?
以下是第一種方法的基本概述:
使您需要的方法成為非靜態(tài)的、非靜態(tài)的。
添加一個(gè)只包含該方法的接口。
實(shí)現(xiàn)接口。
更改對(duì)該方法的引用以使用接口。
我們來看一個(gè)例子:
如果我們對(duì)GetLostOrders方法感興趣,我們可以應(yīng)用步驟1-3來獲得:
現(xiàn)在我們可以在代碼中為這一個(gè)方法更改引用。
現(xiàn)在讓我們看看第二種技巧,包裝和委派。下面是包裝和委派方法的概要:
創(chuàng)建一個(gè)包裝類,用于包裝靜態(tài)類調(diào)用。
將靜態(tài)類中的所有方法實(shí)現(xiàn)為包裝類中的非靜態(tài)方法。每個(gè)方法只委托給靜態(tài)類中的靜態(tài)方法。
創(chuàng)建一個(gè)包含所有方法的接口。
擁有包裝器類實(shí)現(xiàn)接口。
下面是一個(gè)這樣做的示例,給出了與第一個(gè)示例相同的原始代碼:
對(duì)LostOrderService的引用將被重構(gòu),與第一個(gè)示例中的重構(gòu)完全相同,所以這里不包括它。
你可以在這個(gè)例子中看到,我們沒有觸及LostOrderService本身,只是你可能想在類上放置一個(gè)過時(shí)的屬性,告訴用戶不要使用它,而是使用包裝類。
哪個(gè)更好?
過去我傾向于使用包裝和授權(quán)的方法,但我開始認(rèn)為分步方法更好,原因有幾個(gè):
對(duì)于以后使用該類的人來說,分步方法更為明顯。當(dāng)您包裝并委托時(shí),必須有人知道有一個(gè)包裝類。使用分步方法時(shí),別無選擇。
使用分步方法時(shí),實(shí)際上是在擺脫壞的和有害的靜態(tài)方法。當(dāng)您包裝并委托時(shí),您仍然把它們留在那里,只是把它們藏在包裝袋里。
對(duì)我來說,包裝方法更像是我在處理事情,而不是清理它們。我還覺得有人可以看到我開始的東西,然后一步一步地從那里撿起來。如果使用包裝方法,混亂可能永遠(yuǎn)不會(huì)得到清理,因?yàn)橛幸粋€(gè)解決辦法。
包裝和委派的閃耀之處
如果您無法控制靜態(tài)類或靜態(tài)調(diào)用的源代碼,則無法執(zhí)行分步方法。
當(dāng)您處理代碼中對(duì)無法更改的外部庫的靜態(tài)引用時(shí),wrap和delegate方法可以成為救命稻草。您可以簡單地包裝外部庫調(diào)用,而不是在代碼中引用包裝器?,F(xiàn)在您可以實(shí)際對(duì)代碼進(jìn)行單元測(cè)試。
無論何時(shí)使用外部庫,您都應(yīng)該考慮在其周圍放置某種保護(hù)性包裝。您永遠(yuǎn)不知道何時(shí)需要替換它或升級(jí)庫。您不想在所有代碼中查找引用。
因此,盡管這兩種方法都可行,但如果我可以訪問靜態(tài)類的源代碼,我更喜歡使用分步方法。
你覺得呢?你還有別的解決辦法嗎?評(píng)論區(qū)里告訴我哦!
作者介紹
熱門博客推薦