路漫漫其修遠兮,吾將上下而求索——小酌重構系列[0]開篇有益

来源:http://www.cnblogs.com/keepfool/archive/2016/04/23/5423729.html
-Advertisement-
Play Games

相信博客園的讀者大多都是千萬“碼農”中的一員,每個人都寫過很多代碼,但並不是每一個人都能寫出高質量的代碼。rome is not built in one day !——完成高質量的代碼也不是一蹴而就的。為了寫出高質量的代碼,我們需要藉助一些手段,“代碼重構”基本上是最常用的手段,甚至是唯一的手段。 ...


相信博客園的讀者大多都是千萬“碼農”中的一員,每個人都寫過很多代碼,但並不是每一個人都能寫出高質量的代碼。
rome is not built in one day !——完成高質量的代碼也不是一蹴而就的。為了寫出高質量的代碼,我們需要藉助一些手段,“代碼重構”基本上是最常用的手段,甚至是唯一的手段。

重構需要你花一些心思去琢磨自己的代碼,這好比自己種的花花草草,看你怎麼對待它們。你不給它們澆水、除蟲、曬太陽,它們可能會長蟲、生病。如果你用心地去對待它們,它們可能會枝繁葉茂,花開茂盛。但是,即使你已經很專心地去打理它們了,它們也不一定是“健康的”,畢竟每一種花草都有自己的習性,代碼也是如此。

為何要重構?

做一件事情之前,我們都應該先反問自己Why。

我也問過自己:為什麼要對代碼進行重構?項目一個接一個地做,我哪有什麼時間去重構代碼,我還要控制團隊的項目成本!
Oh, Shit!為了讓代碼看起來更好一些,我們花了一些時間在代碼重構上,項目的成本又超了!向公司領導彙報時,又要編造合適的理由了!

我的實際理由是:我們不應該僅僅實現可執行的系統功能,更應該提供高質量的代碼,提升系統的設計以讓其適應更多的變化,如果超出的成本是在可以接受的範圍內,它將符合我們“將來的利益”。

持續利益的提升

何謂“將來的利益”?如果代碼的質量較為可靠,則會為以後的維護、升級奠定良好的基礎。倘若已完成的代碼質量不高、不夠整潔,在系統維護、升級時,不說花在代碼修改上的時間,僅閱讀理解代碼就將花去你大量的時間。如果你需要對項目持續地維護、升級,這該是多麼長久的一個痛苦啊!到這裡,你能理解了吧,這些”低質量代碼“產生的將來成本將遠超於你現在重構的成本。正所謂“長痛不如短痛”,要自宮就趕緊的,這樣才能早點練成“葵花寶典”。

2B地說,重構是為了將來不要掉進自己挖的坑裡。
普通地說,重構是為了提高代碼的可讀性和可維護性。
文藝地說,重構是為了讓代碼的身姿妖嬈美如畫。

設計的提升

沒有完美的產品,也沒有完美的設計,設計的最終目的是為用戶創造價值。大多數系統或產品的設計是伴隨著需求持續演變的,設計調整時,重構又是必備的利器。重構的過程,是對設計過程的整理,也是對設計細節的推敲。設計既然是不完美的,那麼在重構的思考過程中我們總是能發現一些設計上的瑕疵。發現了瑕疵,我們就可以通過重構加以改善。小到對欄位、方法的重構,大到對工程結構、系統架構的重構,都是設計的改變。
這個過程可能讓你痛苦,可能讓你快樂。

何時才重構?

假如你是生活在大山裡的樵夫,為了維持每天的生計,你覺得什麼時間上山砍柴最合適?
是早晨、午後、傍晚、還是晚上?我覺得在早晨和午後較為合適,早晨是最佳時機。
為什麼呢?早晨是人精神最飽滿的時候,也是時間最充分的時候,你可以預先做一些準備,比如:花些時間計劃砍柴的工作量、磨好斧子、準備好捆柴的工具。
如果你選擇午後,你將沒有時間磨斧子,會影響砍柴的效率。
如果你選擇傍晚,砍完柴了天都已經黑了,你是準備住山上嗎?夜間山裡面有各種野生動物,你是想心驚膽戰地過一夜嗎?
如果你選擇晚上,能不能正常上山都是個問題,你別迷路在山間,後半夜的時間都花去早出路了。

講這個例子,並不是為了體現做什麼事情都一定要趁早,而是為了說明無論做什麼事情,選擇合適的時機非常重要。當然趁早做一些事情,也能更早發現問題。

重構亦是如此。重構是一把利器,選擇合適的時機重構或許會讓我們的收益超出預期。

下麵幾項是我覺得可能需要重構的時機:

    1. 代碼中存在著重覆的代碼
    2. 代碼中存在過大的類或過長的方法
    3. 代碼中存在強依賴、緊耦合的結構
    4. 代碼的運算邏輯難以理解
    5. 代碼不能清晰地描述現實對象的特征、行為以及對象間的關係

當然,每個人對重構、對系統、對業務、對用戶的理解是不同的,所以每個人選擇重構的時機也盡不相同。你大可不必參考這幾項,結合周圍的環境選擇合適自己的(這本身也是一個時機選擇)就好。即使出現這幾種情形,重構也不一定是必須的,這取決於你們的項目經驗、你們心中的準則,也取決於你們看待產品、看待項目的方式。

重構的策略

代碼重構有很多策略,我將基於《31 Days Refactoring》和《Clean Code》這兩本書,以及OOP(面向對象編程)的概念介紹一些常用的重構策略。當然,我不是將書中的內容搬到這裡,我會儘可能地加入自己的理解。

下麵列出了我將要講的重構系列的主題,它們基本都來源於《31 Days Refactoring》。是的,這本書只有50多頁,你懂點英文,這本書你花1個小時或許就看完了。重構的代碼大家都能讀懂,我不想徒有其“表”,我想更深層次地理解其“意”,不僅於自己,也於讀到這一系列文章的人。

方法、欄位重構

    1. 移動方法
    2. 提取方法、提取方法對象 
    3. 方法、欄位的提升和降低
    4. 分解方法
    5. 為布爾方法命名
    6. 引入對象參數

類、介面重構

    1. 使用委派代替繼承
    2. 提取介面
    3. 解除依賴
    4. 分離職責
    5. 提取基類
    6. 提取子類
    7. 合併子類
    8. 去除上帝類
    9. 去除中間類
    10. 使用多態代替條件判斷

設計模式重構

    1. 策略模式代替Switch
    2. 引入契約式設計
    3. 提取工廠類

一般性重構

    1. 重命名
    2. 分解複雜判斷
    3. 用條件判斷代替異常
    4. 避免雙重否定
    5. 儘快返回
    6. 用條件判斷代替異常
    7. 封裝條件
    8. 封裝集合

你們也看到了,列舉的這些重構策略都是一些基本技巧,即使學會這些技巧也不能讓你馬上成為“重構”大師,我自身也不是什麼代碼高手。

重構的雙刃劍

事物總是存在兩面性的,重構亦是如此。重構是一把雙刃劍,用得好則能卸磨殺驢,用不好則傷己傷人。

並不是每一次重構,都能然讓你的收益大於支出。重構可能會產生新的bug,加重項目的開發負擔,甚至讓項目版本回滾(這些事情我都已經碰過瓷兒了)。在設計層面,不當地重構可能會破壞原有的設計,甚至破壞系統現有的功能。

正所謂“不破不立”,你不去用劍,不和劍交流,不被劍傷,你永遠無法成為一名好劍客。

後話

最後,我想引用屈原的一句名言:“路漫漫其修遠兮,吾將上下而求索”。

我無法讓你們在看完這一系列文章後,就能“深度”領會重構的“意”了,這仍然需要你自己去琢磨代碼層面的一些事兒,也許是一個方法,也許是項目的架構。

另外,我個人是不推薦“1天學會xxx”、“3天掌握xxx”、”8天弄懂xxx“的。你讀完了文章,不代表你真的理解了。你需要自己去思考,自己去實踐。1天也好,3天也罷,若你肯花時間專心地去領會一件事情,並堅持不懈地為之努力,你遲早是懂的。他人講得天花亂墜,你聽過看過之後,也不過是過眼雲煙。

讀到這一系列文章的讀者,如果有不同的見解,或者察覺文章中的描述有誤,歡迎來討論或指正。通過這一系列文章,我希望讀者會有所收益,也希望自己對重構能有一個更深的理解。如果您覺得文章對您有用,請不要吝嗇您的“推薦”;但如果您覺得它一無是處,請您不要客氣地點擊“反對”,您的反對也是給予我的一種磨礪,它會讓我持續學習和改進。

“多麼痛的領悟~,維護曾是你的全部~~。願你掙脫爛代碼的枷鎖,各種坑的束縛,別再為項目受苦~~~”。結尾獻給各位一首歌,祝大家周末愉快!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 系統中對應的文件是/etc/inittab # Default runlevel. The runlevels used by RHS are:# 0 - halt (Do NOT set initdefault to this)# 1 - Single user mode# 2 - Multius ...
  • 先查看一下系統版本,本例採用的操作系統是CentOS 6.5: 如果你是初裝之後的操作系統,那麼有可能wget這個組件是不存在的,所以你要安裝一下它,這樣才可以讓你從網上down下你要的安裝包: 上面這幅圖是檢查一下你是否安裝過wget組件,如果沒有的話用下麵這條語句安裝一下它即可: 當然如果你不檢 ...
  • 在請求WebApi 的時候,我們更想知道在請求數據的時候,調用了哪個介面傳了什麼參數過來,調用這個Action花了多少時間,有沒有人惡意請求。我們可以通過記錄日誌,對Action進行優化,可以通過日誌追蹤是哪個用戶或ip惡意請求。 在項目中引用log4net.dll 定義一個WebApiMonito ...
  • ahsupermarketshopping AH外貿公司英文企業網站源碼 http://www.51aspx.com/Code/AHForeignTradeCompanyrayxietongoa RayOA協同辦公服務平臺源碼 http://www.51aspx.com/code/RayXieTon ...
  • 昨天是周五太放鬆了,晚上沒有加班只顧著放鬆,玩了一晚上,今天又是睡了一上午,沒有學習。這下放鬆過分了沒有總結,也沒有完成任務。今天來總結一下昨天的學習成果。 昨天設計的資料庫今天老大點評了一下發現問題確實很多。比如用戶表和許可權表的拆分問題,是否應該拆分取決於許可權的使用頻率。使用頻率高時因該拆分。 對 ...
  • 近些天,看了一些博客園大牛關於webApi項目的的文章,也有請教師兄一些問題,自己做了個Demo試了試,收穫甚多。感謝感謝,下麵是我一些學習的總結,如若有錯的地方請多多指教!! WebApi登陸與身份驗證 因為在調用介面的時候都必須傳sessionKey參數過去,所以必須先登錄驗證身份。 如果是已註 ...
  • 今天幫同事看一個問題,她用為了實現動畫效果用主線程執行Thread.Sleep,然後界面就卡死了。 這個問題好解決,new 一個Thread就行了,但是更新WPF的界面需要主線程的操作,然後習慣性的打出Invoke,但是居然沒有。百度了一下發現WPF要用Dispatcher.Invoke ,故寫篇日 ...
  • 兩種方法,一種是利用error.StackTrace,另外一種是try-catch找到錯誤行數,具體如下: 一、error.StackTrace代碼 int i = ex.StackTrace.IndexOf("行號"); 二、try-catch代碼 try { //////////////// / ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...