路漫漫其修遠兮,吾將上下而求索——小酌重構系列[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
更多相關文章
  • 菜鳥要飛系列目錄 1.(菜鳥要飛系列)一,基於Asp.Net MVC5的後臺管理系統(前言) 2.(菜鳥要飛系列)二,基於Asp.Net MVC5的後臺管理系統(實現登陸功能) 3.(菜鳥要飛系列)三,基於Asp.Net MVC5的後臺管理系統(用戶的增刪改查功能) 4.(菜鳥要飛系列)四,基於As ...
  • 最近由於伺服器變更為Linux系統.MsSql for Linux什麼時候出來到生產環境使用還是要很長時間的.於是考慮使用Mysql資料庫,ORM使用EF.於是先踩下坑順便記錄一下,有需要的tx可以參考下.當你考慮使用EF連接Mysql的時候肯定是已經在網上搜了一堆教程.網上教程基本都是使用控制台做 ...
  • 現在在Windows下的應用程式開發,VS.Net占據了絕大多數的份額。因此很多以前搞VC++開發的人都轉向用更強大的VS.Net。在這種情況下,有很多開發人員就面臨瞭如何在C#中使用C++開發好的類的問題。下麵就用一個完整的實例來詳細說明怎樣用托管C++封裝一個C++類以提供給C#使用。 比如,現 ...
  • EF6開始提供了通過async和await關鍵字實現非同步查詢和保存的支持(.net 4.5及更高版本)。雖然不是所有的操作都能從非同步中獲益,但是耗時的操作、網路或IO密集型任務中,使用非同步可以提升客戶端性能和增強伺服器的擴展性。 本文將覆蓋一下主題: 實例演練非同步操作 創建模型 創建同步程式 改為異 ...
  • 所有需要賬戶登錄的website 基本都會想到這樣一個問題, 如何保持用戶在一定時間內登錄有效。 最近本人就在項目中遇到這樣的需求,某些頁面只能Admin賬戶登錄後訪問, 當登錄Admin賬戶後如何才能保持登錄信息呢? 用Cookie或者Session來保存登錄信息已經是一種比較成熟的技術。但是對於 ...
  • 1.這裡僅對web控制項而言,onclick事件執行的是客戶端中的代碼, 可以把事件寫在html頁面上,也可以放在調用的js文件中(此處為A.js)。 A.js: 運行結果: 2.onserverclick事件,這個是執行服務端的方法。 對應的在後臺補充相應的事件: 執行結果: 註意,當onclick ...
  • EF框架對資料庫的連接提供了一系列的預設行為,通常情況下不需要我們太多的關註。但是,這種封裝,降低了靈活性,有時我們需要對資料庫連接加以控制。 EF提供了兩種方案控制資料庫連接: 傳遞到Context的連接; Database.Connnection.Open(); 下麵詳解。 傳遞到Context ...
  • 中間因為比較忙,空了那麼多天,都感覺有點罪過了。話不多說,這一篇主要是要講C#2.0提出的一個新特性,那就是泛型。(現在都C#6.0了。囧囧) 1、什麼是泛型? C#1.0中的委托特性使方法可作為其他方法的參數來傳遞,而C#2.0中提出的泛型特性則使類型可以被參數化,從而不必再為不同的類型提供特殊版 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...