在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

「重構:改善既有代碼的設計」實戰篇

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-08-14 10:42 ? 次閱讀

背景

在軟件開發的世界里,代碼重構是提升項目質量、適應業務變化的關鍵步驟。最近,我重新翻閱了《重構:改善既有代碼的設計 第二版》,這本書不僅重新點燃了我對重構的熱情,還深化了我的理解:重構不僅僅是代碼層面的整理,它更是一種軟件開發的哲學,強調持續改進和適應變化的重要性。

?

書中通過詳細的案例分析和代碼示例,將理論與實踐巧妙地融合在一起。我尤其贊賞作者如何將復雜的重構任務拆解成一系列的小步驟,每一步都被精心設計和考慮,大大降低了重構過程中的風險,同時提高了整個過程的可控性。

?

在這篇文章中,我將通過《重構:改善既有代碼的設計 第二版》書中知識、以及結合在過去幾年中的重構經歷(大到系統架構、核心接口、底層數據存儲、小到簡單的一個方法),分享一些關于重構的感悟和心得。通過有真實的場景、實際重構案例的剖析,我們可以更深刻地理解重構不僅是代碼層面的改進,更是一種思維方式,指引我們如何在不斷變化的業務需求面前,持續優化和提升軟件的質量與效能。

一、重構的定義與理念

正確定義問題,比解決問題重要一百倍。那我們首先來搞清楚什么叫重構?

作為(名詞),重構是指在不改變軟件外在功能的前提下,調整其內部結構的過程。這樣的調整旨在提高軟件的可理解性和降低修改成本。

作為(動詞),重構意味著通過一系列細微的步驟,不斷地調整軟件結構,以保持其設計的整潔和可維護性。

重構是一種精練的技藝,它通過小的、計劃好的修改來減少引入錯誤的風險。本質上,重構是對已完成的代碼進行設計上的改進。

開展高效有序的重構,關鍵的心得是:小的步子可以更快前進,請保持代碼永遠處于可工作狀態,小步修改累積起來也能大大改善系統的設計。

二、重構邊界與時機

1)重構邊界

在進行代碼重構時,明確邊界是至關重要的,以確保重構的效果能夠提升代碼質量而不引入新的問題

在軟件架構中,API(應用程序編程接口)和數據庫(DB)的設計至關重要,因為它們分別代表了系統的外部交互界面和內部數據存儲機制。良好的設計不僅能夠提高系統的穩定性、可擴展性和可維護性,而且在未來進行代碼重構或系統升級時,也能大大減少對上游服務和數據遷移的影響。

wKgaoma8GXmAMO9OAAE_PqHz0mw292.png

1.1)API設計的重要性

1.抽象層次:API作為系統與外界交互的接口,提供了一層抽象,隱藏了底層的業務邏輯和實現細節。這意味著,只要API的接口保持不變,系統內部的實現可以自由變化而不影響外部調用者。

2.穩定性與兼容性:良好設計的API應該考慮到向后兼容性,即使在系統升級或重構時,也能保證對現有客戶端的支持。這減少了上游服務調整的需要,使得系統的迭代更加平滑。

1.2)數據庫設計的重要性

1.擴展性和可維護性:隨著系統的發展,數據量會增加,業務需求也會變化。一個設計良好的數據庫能夠更容易地進行擴展和維護,比如通過合理的索引設計、分表分庫等策略來提高性能。

2.數據遷移的便利性:在系統升級或重構過程中,可能需要進行數據遷移。如果數據庫設計考慮了未來可能的變化,那么數據遷移的工作會相對容易和安全。合理的數據版本控制和遷移腳本也是重要的一環。

1.3)代碼重構的考慮

?分離關注點:即使內部代碼結構復雜或混亂,通過良好設計的API和數據庫,也可以將內部重構的影響限制在系統內部,避免波及到外部調用者或導致數據丟失、不一致等問題。

?迭代開發:在保持API接口穩定和數據庫設計前瞻性的前提下,可以更自由地對內部代碼進行迭代開發和重構,逐步改進系統的內部質量而不影響外部使用者。

?上游和下游的協調:良好的API和數據庫設計,可以減少在系統升級或重構時對上游服務的影響和對數據庫的數據遷移需求。這意味著,即使需要進行較大的內部修改,也能保障系統的整體穩定性和數據的一致性。

總之,API和底層數據庫的設計是軟件架構中的關鍵部分,它們的良好設計是確保系統長期健康發展的基石。通過投入足夠的時間和資源來設計和實現高質量的API和數據庫,可以在系統的整個生命周期中節省大量的時間和成本,尤其是在進行必要的代碼重構時。

?

2)為什么要重構

提高開發效率:通過改善代碼的可讀性和可維護性,重構不僅提高了開發團隊的效率,使其能更快地理解和修改代碼,而且還增強了代碼的靈活性和易修改性,支持敏捷開發的核心要求——快速響應變化。這樣,當業務需求變動時,經過良好重構的代碼庫能夠迅速適應新需求,從而有效促進敏捷開發流程,而不會阻礙變更。

?

減少后期成本:未經重構的代碼會隨著時間推移越來越難以維護。在敏捷開發中,這種情況會導致迭代速度下降和成本上升。通過定期重構,可以持續優化代碼結構,減少后期的維護成本。

3)什么時候重構

3.1)線上痛點&風險可控

書中給了一條準則:第一次做某件事時只管去做;第二次做類似的事會產生反感,但無論如何還是可以去做;第三次再做類似的事,你就應該考慮重構。重構的節奏是小步前進,保持代碼始終處于可工作狀態,從而大幅改善系統設計。

案例:訂單中間件xml節點解析代碼重構 背景:代碼解析xml節點到處都是,根據業務不同解析不同節點,每次修改的點比較多,并且有時候容易遺漏,導致線上問題 重構前代碼:解析xml代碼各種散亂

重構后:節點解析統一收口

重構后效果: 1、重構后節點解析獨立,每個節點對應1個方法,通用性強,以前門檻高,只能專人修改,現在團隊都可修改 2、系統穩定性更健壯 3、需求迭代效率更高

?

3.2)預備性重構:新需求功能更容易

預備性重構可以讓添加新功能變得更加容易,而幫助理解的重構則使代碼更易懂,重構的最佳時機就在添加新功能之前。在動手添加新功能之前,看看現有的代碼庫,此時經常會發現:如果對代碼結構做一點微調,未來需求的工作會容易得多

案例:XXX業務層重構建設 背景:現在業務識別散亂在各個模塊,導致每次業務需求,需要了解并修改所有模塊的相關部分,同時測試也需要全模塊覆蓋,增加需求消耗,同時結構混雜,維護和新人接收都有一定的困難。

重構前代碼方法混亂(總共470行)

重構后代碼主方法(52行)職責清晰

重構后效果: 1、長期價值:代碼結構清晰、可讀性強、不容易出錯、穩定性更健壯 2、長期價值:需求交付周期提升60+%,之前需求5+人日(需要修改N個地方),可提升到2人日(統一收口)

3.3)預備性重構:數據優化減負

在面對不斷變化的業務需求時。預備性重構不僅僅是對代碼的改進,也包括對數據的優化和減負。隨著業務的發展和數據的積累,系統中的數據量會不斷增加。這不僅會增加存儲成本,還可能導致數據處理效率下降,進而影響系統的響應速度和用戶體驗。通過預備性重構中的數據優化減負,我們可以提前解決這些潛在問題,確保系統的可擴展性和性能。

案例:X緩存數據瘦身 背景:xxx 重構前: 緩存:存儲空間使用率60%

重構后:存儲空間使用率30% 重構效果: 1、提高資源利用率,解決緩存數據量大問題(內存使用率從60%降低到30%)

2、增強業務擴展性,為未來的業務擴展打下堅實的基礎。

?

4)什么時候不需要重構

上面講解了什么時候時候重構,但大部分情況下是不需要重構的。比如我看見一堆凌亂的代碼,但日常并不需要修改它而且它也比較穩定,那么我就不需要重構它。如果丑陋的代碼能被隱藏在一個 API 之下,我就可以容忍它繼續保持丑陋。只有當我有痛點、需要去改動的時候,并且業務支撐擴展性、改動很費勁的時候,有痛點了對其進行重構才有價值。

歸根結底一句話:有痛點(線上問題、需求開發復雜、未來擴展性問題)并且重構風險可控的前提下,才需要重構

案例回顧:xxx重構嘗試 背景簡述: xxx的代碼基礎歷史悠久,承載著復雜的業務邏輯,這些邏輯是經過多代開發人員的手逐漸疊加與優化的。隨著時間的推移,雖然功能日益強大,但代碼結構也變得愈加復雜,從而提升了維護的難度和風險。 重構目標: 本次重構的主要目標是實現代碼結構的清晰化,以便于后續的維護和擴展。我們希望通過重構,將混亂的代碼邏輯整理得更加條理清晰,同時保持現有功能的穩定性。 結論與決策: 盡管重構初衷良好,希望能為后續的維護和開發鋪平道路,但在實際執行過程中,我們遇到了預期之外的挑戰。在深入測試重構后的代碼時,我們發現存在多個之前未被充分考慮的使用場景,這些場景的復雜性和多樣性超出了原先的預期。隨著更多場景的出現,整體的重構風險逐漸升高,不再處于一個可控的范圍內。 經過慎重考慮,團隊決定叫停此次重構嘗試。我們認識到,在當前階段繼續推進重構,可能會引入更多不確定性和潛在的風險,從而影響到核心業務的穩定運行。雖然這一決定意味著短期內仍需應對現有代碼結構的挑戰,但從長遠來看,確保業務的連續性和穩定性是我們的首要任務。 未來展望: 雖然這次重構未能如期完成,但它為我們提供了寶貴的經驗和教訓。我們將繼續尋找合適的時機和方法,以更加細致和周全的計劃來逐步優化代碼結構。同時,我們也會加強對現有代碼的理解和文檔的完善,為未來的重構工作奠定堅實的基礎。

?

三、重構的實踐與步驟

軟件重構是一個系統性的過程,涉及到對現有代碼的一系列改進。以下是進行重構的一些常見實踐和步驟

1)清晰的重構目標

明確重構的目的和目標,需要改進的區域。確保團隊成員理解本次重構的價值。比如是因為線上老出問題,還是業務支撐復雜等。

2)逐步重構

梳理清晰:在進行逐步重構的過程中,深入理解現有代碼的功能和設計是前提。這不僅包括對代碼邏輯的把握,還要理解代碼背后的業務邏輯和設計初衷只有全面理解了現有系統,我們才能確保重構的方向和步驟是正確的,同時避免對現有功能造成意外的影響。

逐步重構的精髓:重構并不意味著要一次性進行大規模的改動。相反,它是一個持續的、逐步的過程,通過細小且有序的改進來優化程序的結構。正確的做法是在完全理解現有代碼的基礎上,有條不紊地進行改進,每一次改動后都要通過嚴格且可靠的測試來確保這些改動沒有引入新的錯誤。這種方法既可以提高代碼質量,又能最大限度地減少對項目進度的影響。

大模型AI輔助重構:在這個過程中,充分利用大模型AI技術,可以為重構提供有力的支持。AI可以幫助我們快速理解復雜代碼、發現潛在的重構機會,甚至直接提供重構建議。然而,需要注意的是,AI提供的建議并非總是完全準確。因此,使用AI技術輔助重構時,應將其視為一種參考和輔助工具。我們需要結合自己對項目的深入理解,對AI的建議進行評估和篩選,以確保最終的重構方案既符合項目需求,又能有效提升代碼質量。

案例:2個重復代碼的方法重構合并一個 重構前代碼:

AI建議重構后代碼如下:

AI詳細過程如下:

AI生成單測用例

3)測試和比對

在進行代碼重構時,需要遵循一個不變的初始步驟:確保待修改代碼具備一套可靠的測試。這一步至關重要,因為雖然遵循精心設計的重構策略能夠規避大多數引入錯誤的風險,但作為工程師,出錯的可能性始終存在。隨著程序規模的擴大,不經意間破壞其他代碼部分的風險也隨之增加。

編寫測試:確保有充分的測試覆蓋,涵蓋單元測試、集成測試和系統測試。這些測試在整個重構過程中,是保障功能穩定不受影響的關鍵。

持續集成與自動化測試:通過自動化測試和持續集成,可以確保在重構過程中能夠及時發現并修正錯誤,從而降低引入新錯誤的可能性。

R2引流測試比對重構的測試本質上是一種比對過程。由于每個系統的業務屬性不盡相同,對于讀操作,通過引流比對來驗證功能是比較方便的方法。如果涉及到寫操作,如訂單保存等,則需要對數據的各個關鍵環節進行比對。

回歸測試:完成上述步驟后,進行回歸測試以確保所有現有功能仍然如預期般正常工作。

通過這樣一套全面的測試和驗證流程,能夠確保重構不僅提升了代碼的可維護性和清晰度,同時也保持了系統的穩定性和可靠性。這種方法在追求更好代碼結構的同時,也最大限度地減少了對現有系統功能的影響。

4)切量驗證

在進行重構后的切量驗證時,我們可以依據不同的維度來進行靈活的驗證,例如用戶標識(pin)、訂單的百分比、倉庫等。這樣的切量驗證確保了全鏈路的一致性和穩定性

為了更加謹慎地進行切量,我們建議采用漸進式的計劃,從較小的比例和較長的時間開始,逐步增加。具體的切量步驟可以是:首先從1個或100個開始,然后按照1%、5%、10%、30%、50%、80%直至100%的順序逐步擴大覆蓋范圍。這種方法可以幫助我們在每一步驟中細致地觀察和評估變更的影響,從而確保重構的穩定性和效果。

如果在切量過程中遇到任何問題,我們可以利用DUCC開關快速切換回舊有功能。這種快速回退機制為我們的重構提供了一個安全網,確保了在任何不確定性出現時,我們能夠迅速恢復服務的穩定性和可靠性,最大限度地減少對用戶體驗的影響。

通過這樣細致且靈活的切量驗證策略,我們不僅能夠確保重構的質量和穩定性,還能夠在發現問題時快速響應,確保服務的持續可用性。

5)重構后評估

在完成重構工作后,對重構成果進行全面評估是確保目標達成的關鍵一步。這不僅涉及到驗證重構是否滿足了預定目標,還包括了對系統性能、代碼可維護性和可讀性的綜合評估。

性能評估:首先,我們需要對系統的性能進行再評估。這是為了確保重構工作沒有導致任何性能上的退步。重構的目的往往是為了優化和改進,因此,驗證性能是否至少保持不變(如果不是有所提升的話)是至關重要的。

維護性評估:接下來,我們要評估重構是否有效提高了代碼的可維護性和可讀性。代碼的可維護性是軟件質量的關鍵指標之一,優化代碼結構、減少復雜度和增強代碼的可讀性都是重構的常見目標。通過評估這些方面的改進,我們可以確定重構是否達到了預期的效果。

通過遵循這些評估步驟,重構可以以一種有序和系統化的方式進行,這不僅最小化了引入新問題的風險,還有助于提升軟件的整體質量。最終,這將使得軟件更加健壯、易于維護,并且能夠更好地適應未來的變化和需求。

四、重構的挑戰

盡管重構對維持和提升軟件質量至關重要,但它也伴隨著一定的成本和風險挑戰。理解這些成本和風險對于成功實施重構計劃至關重要。

1)重構的成本

1.1)時間和資源消耗

重構是軟件開發過程中一項至關重要的工作,但它確實需要投入相當的時間和人力資源,特別是在處理大型項目時。這種投入有時可能會對新功能的開發進度產生暫時的影響。開發團隊必須在維護既有代碼的穩定性和引入新功能之間尋找一個恰當的平衡點。

在重構階段,一些新功能可能需要在兩個不同的代碼基礎上實施:一是現有的未重構代碼,二是正在重構的新代碼。以一個為期三個月的重構周期為例,這期間上線的新功能不僅要在原有的代碼架構中實現,還需要在新重構的代碼中進行相應的集成。這實際上意味著同一個功能點需要被開發兩次,以確保功能的連續性和系統的整體穩定性。

這種做法雖然在短期內增加了工作量,但從長遠來看,是確保軟件質量和可持續發展的必要步驟。通過這樣的策略,我們可以在不犧牲軟件穩定性和用戶體驗的前提下,逐步提升代碼質量,同時確保新功能能夠及時地交付給用戶。

1.2)延緩新功能開發

尤其是在緊迫的項目截止日期前,重構可能會對業務產生短期內的負面影響。在緊張的開發周期中,分配資源給重構可能會導致耗時較長的新功能延遲開發。

案例:XXX架構升級 重構目標: 1)打造更清晰的業務邊界和更純凈的內核計算邏輯。引入一套高效的時效計算緩存機制,成功地節省了高達一半的硬件資源費用。 2)增強了系統的復用性,同一套核心計算模式能夠適應預約和非預約兩種不同的業務場景,包括結算、商詳以及下單前后的處理 重構成本挑戰:面臨的最大挑戰之一是重構工作本身的成本,這不僅包括直接的開發、測試成本,還有可能因為重構而推遲開發新功能的機會成本。時間成本:從xxxx到xxxx時候。由于需求的迭代和調整,我們不得不將上線時間推遲至N月份,這意味著在這期間新需求需要再重構前和重構后兩邊都進行開發。

2)重構的風險

2.1)引入新的錯誤

盡管重構的根本目的是提升代碼質量,但在修改現有代碼的過程中,總存在引入新錯誤的風險。為了盡量避免這種情況,建立嚴格的測試流程至關重要,以確保重構過程不會損害現有功能的正確性和穩定性。

在面對復雜的歷史代碼和豐富的業務場景時,單靠人工梳理和自動化測試可能還不夠,因為這些方法可能會遺漏一些細節。在這種情況下,重構測試的一個基本原則是進行精確的比對:確保重構前后,相同的輸入(入參)會產生相同的輸出(出參)。為了實現這一點,可以充分利用泰山R2流量錄制回放技術。

通過靈活設定回放結果的比對策略,我們可以有效地減少排錯的工作量。例如,確定哪些字段可以忽略不計,哪些輸出字段是核心關注的點。這要求測試團隊對API接口的輸入輸出參數以及業務邏輯非常熟悉,以便能夠制定出合理的比對策略。根據不同的測試場景,可以靈活采用關鍵字段對比、結構對比等多種策略。

R2流量回放的優勢在于,它能夠利用線上的實際流量來豐富測試用例,從而使測試更加精準和全面。這種方法不僅提高了測試的效率,還大大增強了測試的覆蓋范圍,使得重構過程更加穩健,有效降低了引入新錯誤的風險。

?

五、重構小技巧

書中通過具體的代碼示例展示了如何執行重構,并解釋了每種重構的動機、做法和效果。以下是一些重要的重構技術和案例:

1)提煉函數(Extract Function)

提煉函數(Extract Function)是一種重構技術,它的目的是將一個大的函數拆分成若干個小的、功能單一的函數。這樣做可以提高代碼的可讀性、可維護性,并且可以復用那些小的函數。

讓我們通過一個簡單的例子來說明這個概念。假設我們有一個函數,它的任務是為一個在線商店的用戶創建一個賬戶,并發送一封歡迎郵件。

重構前:

public class AccountService {
    public void createAccount(String email, String username, String pwd) {
        if (email == null || email.isEmpty()) {
            throw new IllegalArgumentException("Email cannot be empty.");
        }
        if (username == null || username.isEmpty()) {
            throw new IllegalArgumentException("Username cannot be empty.");
        }
        if (pwd == null || pwd.isEmpty()) {
            throw new IllegalArgumentException("pwd cannot be empty.");
        }
        
        // 在這里插入數據庫操作代碼,創建賬戶
        
        // 發送歡迎郵件
        String welcomeMessage="Dear " + username + ", welcome to our service!";
        // 在這里插入郵件發送代碼
    }
}

在這段代碼中,createAccount方法同時負責驗證輸入、創建賬戶和發送郵件。我們可以通過提煉函數來拆分這個方法。

重構后:

public class AccountService {
    public void createAccount(String email, String username, String pwd) {
        validateAccountDetails(email, username, pwd);
        insertAccountIntoDatabase(email, username, pwd);
        sendWelcomeEmail(username);
    }

    private void validateAccountDetails(String email, String username, String pwd) {
        if (email == null || email.isEmpty()) {
            throw new IllegalArgumentException("Email cannot be empty.");
        }
        if (username == null || username.isEmpty()) {
            throw new IllegalArgumentException("Username cannot be empty.");
        }
        if (pwd == null || pwd.isEmpty()) {
            throw new IllegalArgumentException("pwd cannot be empty.");
        }
    }

    private void insertAccountIntoDatabase(String email, String username, String password) {
        // 在這里插入數據庫操作代碼,創建賬戶
    }

    private void sendWelcomeEmail(String username) {
        String welcomeMessage="Dear " + username + ", welcome to our service!";
        // 在這里插入郵件發送代碼
    }
}

在重構后的代碼中,我們將createAccount方法中的三個主要任務分別提煉到了三個獨立的私有方法中。每個方法都有明確的職責:驗證賬戶信息、插入賬戶到數據庫和發送歡迎郵件。這樣的代碼更加清晰,每個部分都更容易理解和測試。此外,如果將來我們需要在其他地方驗證賬戶信息或發送郵件,我們可以復用這些已經提煉出來的方法,增加了代碼的可重用性。

2)內聯函數(Inline Function)

內聯函數(Inline Function)是一種重構技術,用于將一個函數的內容移動到該函數被調用的地方,然后移除原函數。這種技術通常用于當一個函數的體積非常小,而且只被使用一次或者函數的內容幾乎和它的名字一樣清晰時。

下面我們通過一個例子來說明內聯函數的重構過程。

重構前的代碼

在這個例子中,我們有一個LogisticsService類,它有一個calculateShippingCost方法,這個方法只是簡單地調用了另一個方法getBaseShippingCost。如果getBaseShippingCost方法只在這里被調用,我們就可以考慮使用內聯函數。

public class LogisticsService {
    public double processOrder(Order order) {
        // 其他處理邏輯...
        doubleshippingCost= calculateShippingCost(order);
        // 其他處理邏輯...
        return shippingCost;
    }

    private double calculateShippingCost(Order order) {
        return getBaseShippingCost(order);
    }

    private double getBaseShippingCost(Order order) {
        doublebaseCost=0.0;
     
        return baseCost;
    }
}

重構后的代碼

現在我們將calculateShippingCost方法內聯到processOrder方法中,并移除calculateShippingCost方法。

public class LogisticsService {
    public double processOrder(Order order) {
        // 其他處理邏輯...
        double shippingCost= getBaseShippingCost(order);
        // 其他處理邏輯...
        return shippingCost;
    }

    private double getBaseShippingCost(Order order) {
        double baseCost=0.0;
        
        return baseCost;
    }
}

在這個重構后的例子中,我們直接在processOrder方法中調用getBaseShippingCost來計算運費,從而去除了多余的calculateShippingCost方法。這樣做簡化了代碼結構,減少了一層不必要的抽象,使得代碼更加直接和清晰。

內聯函數是一種微妙的重構手法,需要謹慎使用,因為如果過度使用,可能會導致代碼重復或者降低代碼的可讀性。通常只有當一個函數不再提供有用的抽象,或者它的內容和名稱幾乎同樣描述性時,才應該考慮內聯。

3)提煉變量(Extract Variable)

?將表達式的結果賦給一個臨時變量,以提高表達式的清晰度。

重構前:

if (order.getTotalPrice() - order.getDiscounts() > 100) {
    // 邏輯處理
}

重構后:

doublenetPrice= order.getTotalPrice() - order.getDiscounts();
if (netPrice > 100) {
    // 邏輯處理
}

4)內聯變量(Inline Variable)

?如果一個臨時變量只被賦值一次,然后被直接使用,可以將其替換為直接使用賦值表達式。

重構前:

doublebasePrice= order.basePrice();
return (basePrice > 1000);

重構后:

return order.basePrice() > 1000;

5)引入參數對象(Introduce Parameter Object)

?將多個函數參數替換為一個對象,當多個函數共享幾個參數時尤其有用,常用context上下文數據傳遞

重構前:

public void trest(String logPrefix, A a,B b,C c) {
 //業務邏輯處理
}


重構后:

public void trest(Context context) {
  //業務邏輯處理
}


6)分解條件表達式(Decompose Conditional)

?將復雜的條件邏輯分解為更清晰的邏輯塊,提高其可讀性。

重構前:

public void applyFee(Account account) {
    if (account.getBalance() < 0 && account.isOverdraftEnabled()) {
        account.addFee(OVERDRAFT_FEE);
    }
}

重構后:

public void applyFee(Account account) {
    if (shouldApplyOverdraftFee(account)) {
        account.addFee(OVERDRAFT_FEE);
    }
}
private boolean shouldApplyOverdraftFee(Account account) {
    return account.getBalance() < 0 && account.isOverdraftEnabled();
}

7)合并條件表達式(Consolidate Conditional Expression)

?將多個條件表達式合并為一個,簡化邏輯判斷。

重構前:

if (isSpecialDeal()) {
    total = price * 0.95;
} else {
    total = price * 0.98;
}

重構后:

total = price * (isSpecialDeal() ? 0.95 : 0.98);

8)移除死代碼(Remove Dead Code)

?刪除不再被使用的代碼,減少維護負擔。

重構前:

重構后:

?重構切量驗證完成后,確保老代碼無用,可直接刪除主贈老邏輯calcTransferTimeForGift方法以及下面依賴的方法(前提是這些方法沒有其他地方依賴使用)。

書中強調重構不僅僅是改善代碼的過程,也是一種發現代碼潛在問題、提高設計質量和促進團隊理解的手段。

六、總結

《重構:改善既有代碼的設計 第二版》是一本值得每位專業程序員閱讀的指南。這本書深入探討了重構的概念、過程、技術和案例,旨在指導開發者如何通過一系列小的、控制風險的代碼修改來逐步改進代碼的內部結構,而不改變其外部行為。這不僅提升了軟件的業務價值和靈活性,也使我們成為了能夠寫出人類易于理解代碼的優秀程序員。

如果您有任何其他關于重構的建議或想法,歡迎評論交流,謝謝!

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 軟件開發
    +關注

    關注

    0

    文章

    625

    瀏覽量

    27469
  • 代碼
    +關注

    關注

    30

    文章

    4836

    瀏覽量

    69119
  • 代碼重構
    +關注

    關注

    0

    文章

    2

    瀏覽量

    1377
收藏 人收藏

    評論

    相關推薦

    【書籍評測活動NO.56】極速探索HarmonyOS NEXT:純血鴻蒙應用開發實踐

    了解并掌握鴻蒙開發的核心技術,以及鴻蒙應用在實際開發中的應用方法。 本書共分為四,共計16章,分別為鴻蒙開發基礎、鴻蒙開發進階、HarmonyOS SDK 開放能力集和鴻蒙特色
    發表于 01-20 16:53

    LwIP應用開發實戰指南—基于野火STM32

    LwIP應用開發實戰指南—基于野火STM32—20210122
    發表于 01-17 14:34 ?0次下載

    探討(三):代碼復用的智慧 - 提升架構的效率與可維護性

    作者:京東物流 馮志文 前兩從服務粒度和服務內的分層架構角度探討,本文繼續從服務間代碼復用角度探討。 背景 在分布式架構中,代碼復用是個難題。那么如何處理代碼功能共享的問題呢?本文結
    的頭像 發表于 12-27 15:58 ?319次閱讀
    探討<b class='flag-5'>篇</b>(三):<b class='flag-5'>代碼</b>復用的智慧 - 提升架構的效率與可維護性

    既有居住社區電動汽車充電樁安裝的困境與破局之策

    15821697760 摘要 :2022 年我國發布的相關政策明確,新建居住社區要確保固定車位百分百建設充電設施或預留安裝條件,而既有居住社區的充電樁建設也亟待推進。本文聚焦既有居住社區安裝電動汽車
    的頭像 發表于 12-17 10:13 ?361次閱讀
    <b class='flag-5'>既有</b>居住社區電動汽車充電樁安裝的困境與破局之策

    淺談既有社區安裝新能源電動汽車充電樁的困境與對策

    本文主要就既有居住社區安裝電動汽車充電樁的困境與對策展開探究,立足當前充電樁建設問題,持續推進既有居住社區安裝電動汽車充電樁工作的開展進程,制定出完善的應對辦法,旨在解決當前具有居住社區充電樁統建統管等的問題,將外部力量和內生動力相結合,開創出問題解決的新局面。
    的頭像 發表于 12-14 10:07 ?370次閱讀
    淺談<b class='flag-5'>既有</b>社區安裝新能源電動汽車充電樁的困境與對策

    建筑能耗監測對既有建筑節能的研究

    摘 要:在建筑能耗監測技術的基礎上,融合建筑能源審計技術性和工程建筑能耗等級評價技術,研究現有建筑的能耗,明確提出節能改造計劃方案。在未來,該研究思路還可以運用于我國既有建筑的節能工作,為未來既有
    的頭像 發表于 11-06 16:59 ?287次閱讀
    建筑能耗監測對<b class='flag-5'>既有</b>建筑節能的研究

    深入解析:純凈IP如何重構互聯網環境

    純凈IP作為互聯網環境中的一個重要概念,正在逐步重構整個網絡環境的面貌。
    的頭像 發表于 10-25 07:36 ?289次閱讀

    鴻蒙Flutter實戰:08-如何調試代碼

    # 鴻蒙Flutter實戰:如何調試代碼 ## 1.環境搭建 參考文章[鴻蒙Flutter實戰:01-搭建開發環境](https://gitee.com/zacks
    發表于 10-23 16:29

    建筑能耗監測對既有建筑節能的研究分析

    摘 要: 在建筑能耗監測技術的基礎上,融合建筑能源審計技術性和工程建筑能耗等級評價技術,研究現有建筑的能耗,明確提出節能改造計劃方案。在未來,該研究思路還可以運用于我國既有建筑的節能工作,為未來既有
    的頭像 發表于 10-15 16:09 ?296次閱讀
    建筑能耗監測對<b class='flag-5'>既有</b>建筑節能的研究分析

    【全新課程資料】正點原子《ESP32物聯網項目實戰》培訓課程資料上線!

    、真正的手把手教學: 項目實戰階段,我們將手把手帶您開發APP界面以及核心代碼,逐步實現所需的功能,以此來提高編程的能力 四、適合群體 本課程會從基礎入門過渡到項目實戰,層層遞進,因此非常適合以下
    發表于 09-24 17:05

    代碼整潔之道-大師眼中的整潔代碼是什么樣

    幾個月前寫了一文章“如何寫出難以維護的代碼”,從中能大概了解到不好維護的代碼是什么樣,有哪些壞味道,那肯定有人會反問,難以維護的代碼見的太多了,也知道長什么樣,但是對于好維護的
    的頭像 發表于 09-09 16:30 ?432次閱讀
    <b class='flag-5'>代碼</b>整潔之道-大師眼中的整潔<b class='flag-5'>代碼</b>是什么樣

    擺脫自建庫的繁瑣,EDA元件庫轉cadence原理圖封裝庫實戰技巧

    擺脫自建庫的繁瑣,EDA元件庫轉cadence原理圖封裝庫實戰技巧
    的頭像 發表于 08-24 12:29 ?3267次閱讀
    擺脫自建庫的繁瑣,EDA元件庫轉cadence原理圖封裝庫<b class='flag-5'>實戰</b>技巧

    華為用“三個重構”為筆鋒,書寫全球數字金融大文章

    重構韌性和智能,給全球金融注入新動力
    的頭像 發表于 06-11 09:28 ?1954次閱讀
    華為用“三個<b class='flag-5'>重構</b>”為筆鋒,書寫全球數字金融大文章

    工廠高精度人員定位系統改善了哪些方面呢?

    工廠高精度人員定位系統的改善對于現代工廠管理和生產效率提升具有重要意義。那么,滄穹就在這一文章中便給各位朋友簡單聊聊這些改善主要體現在以下幾個方面
    的頭像 發表于 05-08 14:21 ?323次閱讀
    工廠高精度人員定位系統<b class='flag-5'>改善</b>了哪些方面呢?

    G431CB把stack heap全分配到ccmram,代碼執行速度并未改善是怎么回事?

    把stack heap全分配到ccmram發現函數執行時間也沒有什么改善,附圖是我的結果 函數執行速度非但沒有改善,反而發現在ccmram執行很不穩定; 測試手段:用定時器3計數來實現該函數執行時間的測試,將執行時間輸出到cubemonitor中顯示
    發表于 03-27 08:23
    主站蜘蛛池模板: 久操青青 | 视频在线观看免费播放www | 欧美透逼视频 | 人人射人人澡 | 日本黄色免费在线 | 特黄特黄特色大片免费观看 | 欧美大黄 | 欧美日韩亚洲国产一区二区综合 | 台湾香港澳门三级在线 | 好紧好爽的午夜寂寞视频 | 国产午夜三级 | 日本中文字幕在线播放 | 狠狠色狠色综合曰曰 | 日韩特黄毛片 | 日本黄色免费 | 免费高清成人啪啪网站 | 国产成人啪精品午夜在线观看 | 日韩毛片网站 | 久久久综合视频 | 在线天堂bt种子 | 久久福利青草精品资源站免费 | 日日射天天射 | 国产美女视频一区二区二三区 | 巨乳色网址 | 欧美疯狂爱爱xxxxbbbb | 亚洲第一视频网 | 日本黄网站高清色大全 | 黄色网在线看 | 人人洗澡人人洗澡人人 | 午夜短视频 | 丁香婷婷网 | 最新四虎4hu影库地址在线 | 日日射夜夜 | 色综合色综合色综合色综合网 | 中国美女乱淫免费看视频 | 在线欧美激情 | 在线观看视频免费入口 | 黄乱色伦 | 永久看片 | 国产精品久久久久网站 | 色之综合天天综合色天天棕色 |