為什麼軟體開發需要重構?

經驗上,一開始的設計總是會有問題的。


正好最近在整理跟重構理論及發展相關的材料。

先上結論:其實軟體開發並不一定需要重構

作為《重構》這本書的譯者,我有一個觀點:重構已死。當然這種「xx已死」的調調一聽就知道是嘩眾取寵的。更加嚴格的說法應該是:《重構》書中所描述的、針對面向對象語言單一代碼庫的重構技術,是在一個獨特歷史背景下發展成型的產物;在當今的軟體開發歷史背景下,這種技術的適用範圍正在變窄,且適用的問題域和解決方案都已相當成熟,因此不再有繼續討論的價值

=== 第一更:重構是(和不是)什麼 (2016-01-02) ===

為了使接下來的討論有一個可靠的基礎,首先需要對「重構」(refactoring)這個詞作一個明確的定義。按照《重構》書中的定義:


第一個定義是名詞形式:


重構(名詞):對軟體內部結構的一種調整,目的是在不改變軟體可觀察行為的前提下,提高其可理解性,降低其修改成本。


「重構」的另一個用法是動詞形式:


重構(動詞):使用一系列重構手法,在不改變軟體可觀察行為的前提下,調整其結構。

上述定義中,第一個值得注意的關鍵詞是「不改變軟體可觀察行為」。按照這個關鍵詞,@馮東所說的情景就不是重構(當然,這還取決於他說的「做錯」和「修正」如何定義,我假設「修正一個錯誤」意味著「改變軟體可觀察的行為」)。

第二個關鍵詞是「重構手法」。一次重構之所以能成為一次重構,它必須遵循一定的重構手法,而不是隨便調整。很多人在閱讀這本書的時候只看前四章,真正動手改代碼的時候根本不遵循重構手法,這樣的行為也不是重構。我在這裡採用一個較為嚴格的限定:只有遵循已經發表的重構手法時,才能認為是在進行重構。

第三個關鍵詞是「軟體內部結構」。這實際上是非常有玄機的一個詞。玄機我們暫且按下不表,從Opdyke的論文到《重構》再到《修改代碼的藝術》,重構理論的早期奠基作品談論的都是單進程、單代碼庫的代碼重構。因此,我傾向於將「軟體內部」限定為「單進程、單代碼庫內」。

現在,當我討論「軟體開發是否需要重構」時,我討論的是:

軟體開發是否需要:

  1. 不改變軟體可觀察行為的前提下,
  2. 採用已經發表的重構手法
  3. 單進程、單代碼庫內的軟體結構進行調整。

而我的觀點是:在現代軟體開發的環境下,越來越不需要。

=== 第二更:為什麼重構 (2016-01-06) ===

以下內容出自《重構》第2.2節。我用粗體標註出了一些關鍵詞,這些關鍵詞將有助於我們理解重構技術背後的假設。


重構改進軟體設計


如果沒有重構,程序的設計會逐漸腐敗變質。當人們只為短期目的,或是在完全理解整體設計之前,就貿然修改代碼,程序將逐漸失去自己的結構,程序員愈來愈難通過閱讀源碼而理解原本設計。重構很像是在整理代碼,你所做的就是讓所有東西回到應該的位置上。代碼結構的流失是累積性的。愈難看出代碼所代表的設計意涵,就愈難保護其中設計,於是該設計就腐敗得愈快。經常性的重構可以幫助代碼維持自己該有的形態。


重構使軟體更容易理解


所謂程序設計,很大程度上就是與計算機交談:你編寫代碼告訴計算機做什麼事,它的響應則是精確按照你的指示行動。你得及時填補「想要它做什麼」和「告訴它做什麼」之間的縫隙。這種編程模式的核心就是「準確說出我所要的」。除了計算機外,你的源碼還有其他讀者:幾個月之後可能會有另一位程序員嘗試讀懂你的代碼並做一些修改。我們很容易忘記這第二位讀者,但他才是最重要的。計算機是否多花了幾個小時來編譯,又有什麼關係呢?如果一個程序員花費一周時間來修改某段代碼,那才關係重大—如果他理解你的代碼,這個修改原本只需一小時。


重構幫助找到bug


對代碼的理解,可以幫助我找到bug。我承認我不太擅長調試。有些人只要盯著一大段代碼就可以找出裡面的bug,我可不行。但我發現,如果對代碼進行重構,我就可以深入理解代碼的作為,並恰到好處地把新的理解反饋回去。搞清楚程序結構的同時,我也清楚了自己所做的一些假設,於是想不把bug揪出來都難。


重構提高編程速度


我強烈相信:良好的設計是快速開發的根本──事實上,擁有良好設計才可能做到快速開發。如果沒有良好設計,或許某一段時間內你的進展迅速,但惡劣的設計很快就讓你的速度慢下來。你會把時間花在調試上面,無法添加新功能。修改時間愈來愈長,因為你必須花愈來愈多的時間去理解系統、尋找重複代碼。隨著你給最初程序打上一個又一個的補丁,新特性需要更多代碼才能實現。真是個惡性循環。

從這幾個重構的原因中,我們看到了下列幾個(我在引文中加粗的)關鍵詞,我們可以來分析一下它們背後隱含的假設:

  • 短期目的 =&> 編程時僅考慮短期目的是不好的,也就是說,代碼庫有比較長的生命周期。
  • 另一位程序員 =&> 在這個代碼庫上工作的人數會比較多,且人員的變動比較頻繁。
  • 一大段代碼 =&> 代碼庫的規模比較大。
  • 添加新功能 =&> 一個代碼庫承擔多種責任。

所以從2.2節中我們不僅可以讀到為什麼重構,而且可以讀出作者沒有明言的假設:作者在談論的是規模較大、生命周期較長、承擔了較多責任、有一個較大(且較不穩定)團隊在其上工作的單一代碼庫。當然所有這些都是相對度量,例如多少行代碼算大、生存多長時間算長,沒有絕對而清晰的界定。

那麼接下來我們就要問:為什麼重構技術有這樣一些假設?這些假設是在什麼樣的時代背景下形成的?這些假設在今天的時代背景下是否仍然適用?如果這些假設不再適用,重構技術是否仍然適用?

=== 第三更:重構的時代背景 (2016-01-07) ===

可能令人吃驚:重構出現的時間相當早,比Java早,比設計模式早。William Opdyke的博士論文Refactoring Object-Oriented Frameworks(下載PDF)發表於1992年,這篇論文是重構理論的奠基之作。(BTW,Opdyke這位老兄相當牛逼,他的博士導師是GoF之一的Ralph Johnson。)那麼在Java都還沒出現之前,重構的早期玩家們玩的是什麼語言呢?答案是「Smalltalk」,傳說中的「Ruby之根」——好吧,跑題了,打住。《重構》的出版是1999年,所以基本上我們可以認為,重構是上世紀90年代浮現、並在本世紀頭十年引起重視的技術。

於是我們要問了:為什麼在世紀之交的這十多年裡,規模大、承擔責任多的單一代碼庫成為了主流?在一個代碼庫、一個進程里承載一個系統所有的功能,這並不是一個古而有之的做法。例如在一個典型的基於VxWorks的電信系統中,職責劃分不是以函數、而是以進程為單位。即便在Sun推薦的J2EE架構(http://docs.oracle.com/cd/E19683-01/817-2175-10/deover.html)中,業務是分散在若干個EJB中的,每個EJB可以(儘管未必總是會)被部署為一個獨立的進程,所以整個系統也不必(儘管仍然可以)存在於單一代碼庫中。

然而Sun推薦的J2EE架構並沒有被廣泛接受,反倒是以Spring為代表的「輕量級J2EE」最終成為了主流。我在《不敢止步》里講到,「輕量級J2EE」的核心架構思想實際上就是Martin Fowler的分散式對象設計第一法則:

分散式對象設計第一法則:不要分布你的對象!

另一種風格則是Apache、Jon Tirsen、Rod Johnson 等開源先鋒推薦的Martin Fowler 在PoEAA 里總結的:不要分布對象,在一個Java 進程里完成所有業務邏輯, 用集群解決單台伺服器負載過重的問題。這種架構風格,再加上後來的「Shared Nothing Architecture」,實際上就把Web 應用簡化成了一個單進程編程的問題: 不是「使遠程調用變得透明」,而是根本沒有遠程調用。

這個架構風格的最大價值是讓開發者可以在自己的桌面電腦上複製整個生產環境,從而能夠快速修改並看到反饋。「在個人電腦上複製整個生產環境」這件事,只有當個人電腦的性能高到一定程度時才有可能的。在90年代之前,電信、金融、醫療、航天、軍事等主要的IT用戶,其生產環境是很難複製的。所以當時的軟體開發過程必須是瀑布式的,因為修改之後看到效果的反饋周期太長,只好盡量提前把設計做好,開發一次成功。而90年代個人電腦性能的提升、尤其是奔騰CPU的廣泛應用,使「在個人電腦上複製整個生產環境」成為了可能。

而輕量級J2EE則是在這個時間節點上的關鍵一觸,把可能性變成了現實。如果將業務邏輯分布在多個進程中,就不可避免地需要運行多個Java虛擬機進程(甚至多個應用伺服器進程),而這些——在當時的標準下——龐大的進程會耗盡當時大多數桌面開發電腦的性能,從而使反饋周期變長。

能夠在單台個人電腦上複製整個生產環境,這個能力開啟了整個敏捷軟體開發的想像空間。測試驅動開發成為可能,持續集成成為可能,用戶代表跟開發團隊的緊密溝通才有必要,每天的站會、每周的迭代展示和計劃會議在這個反饋周期的節奏下才有意義,注重對話的故事卡在這個節奏下才顯得重要。單一代碼庫、單一進程、不分布對象、伺服器農場式部署的架構風格,其目的是儘可能地保障在單台個人電腦上複製整個生產環境的能力,從而顯著縮短反饋周期。

這就是重構技術走進主流視野的時代背景:摩爾定律使個人電腦堪堪具備足夠的計算能力來複制整個生產環境,敏捷社區迫不及待地用輕量級J2EE架構使「複製整個生產環境」成為現實,在縮短反饋周期的同時也使單一代碼庫不得不承載整個系統的職責,從而使整個代碼庫變得龐大且職責不單一。為了在這樣的代碼庫上繼續快速的「修改-反饋」循環,對這樣的代碼庫進行內部質量保障和改進的技術——測試驅動開發、持續集成、重構——才變得重要。

那麼,十多年以後,我們所處的時代背景發生了哪些變化?這些變化是否會使重構技術變得不再重要?

=== 第四更:今天的世界 (2016-01-13) ===

今天的商業IT環境用一個詞就可以概括:不確定。不確定帶來顛簸和變動,不確定滋生懷疑和恐懼。而這種不確定,從豐田決定用大規模定製的產品來服務消費者的需求、而非僅僅提供某種功能開始,就已經註定了。當產品的目的是提供某種功能,功能的要求和達成的方式是相對確定的,不確定的比例相對較小;而當產品的目的是滿足消費者的需求乃至提供良好的體驗,人的不理性、不邏輯性就開始佔據更大的比重,從而使不確定性的比例顯著增加。Martin Fowler在《企業應用架構模式》里講,所謂「業務邏輯」,實際上是「業務不邏輯」——因為這些業務規則根本不合邏輯,所以它們才需要特別地被提出、被討論、被理解、被確認。這個洞見反映出當代商業IT環境的特徵:現在的商業IT,越來越多地是在建模與迎合人的不理性、不邏輯性。在這個背景下,不確定性的劇增就是不可避免的。

當不確定性還不算太多的時候,對軟體的要求是可維護性:需要加新的功能、需要修改舊的功能,能改得進去。這種「維護」(或者叫「演化」)實際上仍然是基於預測的。整個軟體系統的大致方向已經被預測了,然後在此基礎上談演化。而當不確定實在太多的時候,對軟體的要求就變成了可拋棄性。整本《精益創業》講的就是這麼一回事:你構建(build)的所有東西,都是為了度量(measure)某種數據從而學習(learn)——「學習」的定義是證實或證偽某個假設(hypothesis),而一旦假設被證偽,就要立即轉向(pivot)。換句話說,你開發的所有軟體,都應該做好很快被拋棄的準備。

如何獲得可拋棄性?很簡單:少寫代碼。一萬行代碼扔掉要傷心,一千行代碼隨時扔掉重新寫。從輕量級J2EE的勝利開始,開源軟體在商用軟體領域成為了絕對主流,並展現出巨大的復用優勢:基礎框架越來越成熟,應用編程越來越傾向於用DSL描述業務領域,代碼量越來越少。Spring已經呈現出這個趨勢,Ruby on Rails及之後的框架更將這個趨勢推向極致:開發者可以在最短時間內以最少代碼量做出一個規規矩矩的軟體。開發這樣的業務軟體並不需要多少設計,因為大部分設計已經蘊含在框架內。代碼結構簡單,代碼量少,決定了這樣的代碼庫爛也爛不到哪裡去。而且本來就是以可拋棄性為目標設計的軟體,它的生命周期預期也不會長到讓代碼質量能爛到哪裡去。

但是總有些系統會成功,會向著更複雜的方向演化。然而這時系統的演化就未必要在同一個代碼庫中進行了。在這個階段,軟體的設計者應該能區分出較為穩定的領域模型與較為易變的用戶操作。領域模型與用戶操作兩者變化的頻率不同,實現的技術也不同,完全沒有理由存在於同一個代碼庫中。同時,多渠道、尤其是移動渠道的興起,是另一個推動領域模型與用戶操作分離的動因:領域模型最好是運行在自己的進程中,向各種渠道提供服務,從而在不同渠道之間復用領域邏輯。

於是我們再一次有了「以多個代碼庫、多個進程承載一個系統」的訴求。而這一次,摩爾定律的發展、特別是虛擬化技術的發展,使得「多進程」與「在個人電腦上複製整個生產環境」不再矛盾。正如Sam Newman在《Building Microservices》中所說:

Domain-driven design. Continuous delivery. On-demand virtualization. Infrastructure

automation. Small autonomous teams. Systems at scale. Microservices have emerged from

this world.

在同一本書里,Newman也提到了可拋棄性(他稱之為「可替換性」)的問題:

Teams using microservice approaches are comfortable with completely rewriting services

when required, and just killing a service when it is no longer needed. When a codebase is

just a few hundred lines long, it is difficult for people to become emotionally attached to

it, and the cost of replacing it is pretty small.

既然不必把整個系統塞進一個代碼庫、一個進程,那麼自然可以讓每個代碼庫、每個進程符合單一職責原則,做且僅做一件事。這樣的一個代碼庫規模不會大(儘管未必像Newman所想的只有幾百行代碼),在上面工作的團隊也會很小。這樣的一個代碼庫,它的質量不會爛到哪裡去;即使出現了質量腐化的跡象,在有必要的測試覆蓋的前提下,即使不遵循嚴格的重構手法也足以優化其內部質量;即使——儘管相當不可能——質量腐化到了相當的程度,正如Newman所說,從頭寫過就是了。在這樣的一個代碼庫中,《重構》書中所描述的嚴格的重構技術所能發揮的價值將相當有限。

=== 第五更:尾聲,以及新的開篇 (2016-01-15) ===

簡單總結一下前面講的內容:

  1. 《重構》所介紹的重構技術,是在不改變軟體可觀察行為的前提下,採用已經發表的重構手法,對單進程、單代碼庫內的軟體結構進行調整。
  2. 這種技術適用於規模較大、生命周期較長、承擔了較多責任、有一個較大(且較不穩定)團隊在其上工作的單一代碼庫。
  3. 十多年前,企業應用架構轉向單一代碼庫、單一進程、不分布對象、伺服器農場式部署的架構風格,其目的是儘可能地保障在單台個人電腦上複製整個生產環境的能力,從而顯著縮短反饋周期。
  4. 現在,更高的不確定性使代碼庫生命周期顯著縮短,領域驅動設計和虛擬化技術使每個代碼庫職責單一。因此,在今天的商業IT環境下,重構技術的價值大大降低。

或者,換回嘩眾取寵的調調,我說的是:十五年以後,重構已死

清晰地認識到「重構已死」這一現實很重要。因為這個認識會讓我們開啟一系列更為宏大、影響更為深遠的討論:

  • 雖然單一代碼庫的職責變得簡單,然而整個IT系統的複雜度仍然在。這些複雜度以何種方式表現
  • 雖然單一代碼庫的內部質量不至於嚴重腐化,然而整個複雜的IT系統仍然有可能腐化。一個複雜系統會以何種方式腐化
  • Opdyke在他的論文中介紹了一組行為保持的修改手法,以這些手法對程序進行修改時,對程序外部行為的影響可以被控制在最小範圍。在代碼之外,這些行為保持的修改手法是否普遍適用
  • 測試驅動開發是重構的安全網。在無法使用xUnit的情景下,如何構建安全網
  • Kerievsky在《重構與模式》中指出,重構以設計模式為目標。在面向對象設計模式不適用的場景下,如何確定重構的終點

我的觀點是,雖然《重構》書中所介紹的重構技術已經過時,然而對壞味道重構手法的總結和抽象將指導我們得出廣泛適用的重構思想,這種思想將有助於識別和解決其它複雜IT系統中的內部質量問題。並且由於康威法則(Conway"s law)的作用,這種思想也將有助於識別和解決其它複雜組織系統中的內部質量問題。

用嘩眾取寵的調調來說就是:重構已死,重構思想永生

也許我會就這個題目寫一本書。但願我能寫出來吧。

以上。


  • 「重構」並不是完全打翻重來,最開始的設計也並非一無是處。
  • 軟體開發是一個過程,軟體使用的人群、環境都可能在進行中發生變化,當初設計中的一些假設、條件都會變化,這就需要根據新的狀況做出調整。「重構」是代碼層面的「重設計」,代碼是軟體的實現方式,設計做出調整,代碼當然也要調整。
  • 「重構」也是對原有代碼的完善,消除代碼中的腐臭味,讓代碼更健壯、效率更高、更易維護。這是軟體開發的規律決定的,沒有人能一次寫出完善的代碼。


舉個例子。假設構建一個複雜系統需要考慮10點。由於人本身的局限,你肯定會做錯其中的6點,當然這6點並不影響第一版的發布。然後,你如何修正這6點?

  1. 你不能重寫系統。因為重寫系統你還會做錯6點,雖然可能是不同的6點。
  2. 你不能在增加系統功能的同時修正這6點,因為增加一個功能,就會再增加比如說5點要考慮的東西,這個過程中你又會做錯3點。
  3. 當你不增加新功能,又試圖修復這6點中的某一個或者幾個,這個過程就是『重構』。
  4. 重構並不能保證不會毀掉你原本做對的4點,但是你起碼可以肯定這個錯誤是因為你的重構造成的而不是別的原因(比如第2種做法里新增加的那5點)。而且這也是鼓勵你在第3種做法里盡量只修正一個錯誤。
  5. 你永遠達不到完全做對10點,即使你有無限的時間重構。而實際上你的重構永遠在和添加新功能競爭資源。
  6. 由於第5點,你不要無緣無故的重構,除非需要增加新功能。但是由於第4點,又不能和增加新功能同時進行。

當人類文明的代碼積累到一定程度,我們就不再需要寫新代碼(或者只需要寫膠水代碼即可)。那時的程序員會被稱為考古程序員(因為總是在重構已有代碼)。參考《天淵》。


為什麼不去讀martin fowler的重構一書呢?


你回憶一下自己,當對母語的掌握程度逐漸熟練以後、當自己的辭彙量逐漸增大以後、當對社會的理解加深以後,你會發現小時候說的話的思想很淺薄、表述水平又很低。只要有機會,你很願意重新說一遍

一個人需要20年才能極其熟練地掌握自己的母語和(大致)理解社會;一個程序員最起碼也要20年才能走完對應的道路


個人比較同意@馮東 和 @李申申 的回復,補充一下,我認為,重構這種事情對於還有生命價值的軟體而言,就是必需的。這一點我覺得可以類比人類和任何一種有生命的動物。

任何一種生物都不是完美的,但它(他、她)卻可以在一定程度上適應環境的需求,但是適應的並不完美。所以才需要重構這種不斷地「新陳代謝」和「進化」,保持這個物種在大自然中的競爭力。也只有被淘汰的物種才不需要新陳代謝和進化。

具體的重構的要素,其實軟體工程之類的書籍中都有談到了,上面的同學也談到了很多,這裡就不重複了。


需求是分形,產品是分形,項目是分形,代碼是分形。我們永遠不可能精確完成,只能以迭代的方式無限逼近。代碼重構,就是這迭代的一部分。


什麼是重構呢?重構就是以一種可控的方式,一小步一小步地調整當前的設計。 重構的原因在於在現有的設計中已經無法優雅地實現新增的需求。

原先的設計是建立在對問題空間的認識上,隨著時間的推移,對問題的認識就會產生變化,原有的設計就要進行修改。認識的改變在於:

  • 人對問題的理解總是由零碎,片面、表面、粗略到整體,全面,深刻,精準的。

  • 現實世界的問題本身也在無時無刻地變化中。

作為一種修改設計的方法,重構是建立在面向對象程序設計,單元測試和重構方法的基礎上的。

  • 單元測試保障了每一小步的修改都能夠通過單元測試進行驗證,不影響系統原有的功能。
  • 重構方法,包括 抽取方法, 將屬性或方法上移至父類,或下移至子類,抽取介面,引入中間人,引入參數對象等等。

重構,而不是重寫,降低了對設計進行修改的風險,也就降低了設計階段產生的缺陷的修改成本,也就減少了過度設計的產生。


我的答案可能跟重構沒有任何關係,關於程序開發,我個人認準的兩條準則是「迭代」+「DRY」,從這兩條準則出發,重構就是通過不斷迭代的過程調整程序的結構,消除Repeat Yourself的代碼和構建。


謝邀。

趕paper累了,答個題算是放鬆放鬆吧。

覺得以上都說得挺充分的,我就從另一個角度來說說重構吧。

在博士期間做過一個與重構相關的研究工作,我當時寫過一些代碼來自動分析開源項目庫中的重構情況。思路也很簡單,也就是提取開源項目的Git庫中的各版本,然後逐項比較,通過版本間的代碼修改來自動提取重構操作。我一開始的想法是準備找一些純做重構的代碼提交(commit)來進行分析,但意外是,像在eclipse這樣的極其注重代碼質量的項目中,除了像「重命名」這樣的重構操作,幾乎很難找到一次專門做重構的代碼提交。基本的情況是,包含重構操作的代碼提交確實不少,但這些提交都額外地包含了功能添加或缺陷修改的代碼。就這次觀察的結果而言,重構,就像部隊行軍中的「糧草先行」,它很少憑空無謂地產生,其發生,往往由代碼中其他的「利益」所驅動。

雖然這個研究最後沒有深入做下去,但結論卻也具有一點啟發性。我遇到過一些程序員同學,他們似乎追求著一種「代碼的潔癖」。他們無法忍受代碼的複製粘貼,對設計模式的使用津津樂道。其實,在實際開發過程中,項目的代碼並不是用來欣賞的,更多的情況是給定了一個deadline,然後大家努力趕工完成任務。所以,在大多數實際情況下,重構的意義是保證讓整體的代碼結構不會對代碼生產、維護和理解的效率產生負面影響。因此,重構應該只是寫代碼行為中的一個權衡決策而已。當現有的代碼結構變得開始拖累後續的開發和維護時,無需刻意,重構自然而然成了一種勢在必行的選擇。反之,如果刻意對代碼進行高度復用,反而會和重構本身的意義南轅北轍。從這個角度來說,將設計模式用得眼花繚亂也許只是對到處複製粘貼代碼的一種矯枉過正,哪一個危害更大,其實,並不好說。畢竟,重構,如同生活中的很多事情,貴在自然嘛~


個人經驗,沒有任何建議。

一般是遷移的多 , 全部換另一種方式(編程語言,資料庫等)

重構的少 (同一種語言等)


重構的真實驅動力來源於money,如果軟體在商業上還有生命力,如果重構以後能提高後續軟體維護開發的投入產出比。

現在討論為什麼重構以後可以提高軟體的投入產出比?

假設針對軟體已經實現的功能,以及有把握將要擴展的功能,存在一個最優設計(什麼叫最優設計?先不討論),那麼若不刻意重構,軟體打誕生那一刻起就一定不是最優設計,而且正在漸行漸遠。重構就是把軟體向這個最優設計回歸的過程。

原因有三:

1,工程師的認識在不斷深化,系統開發完了才真正了解系統。還有不少工程師,開發完幾個系統才成長為工程師:-)。很多有潔癖的工程師都恨不得在系統殺青的那一刻推倒重來。

2,設計所依賴的前提在發生變化。通信行業是典型,系統誕生之處連操作系統,程序設計語言還有晶元都要自己開發(回憶一下bell labs都幹了啥?),20年後這些東西都有了價廉物美的選項。

3,漫長生命周期中不斷增加的新需求,這些需求不可能在系統設計之初都預測到,都預測到了也不可能都提前考慮好(這是要成本的),原來的設計可能不是很匹配這些新需求。拗一拗,總算是讓新老需求共處一室了,拗的過程中難免產生累贅的適配層。

至於改bug,走捷徑這些都不講了。

最後,重不重構,一切唯錢是瞻。今天的不少行業,重構和重寫都沒必要,直接扔了,找個現成的軟體配置配置就夠了。更有甚者,拋棄軟體,直接把相關業務委託給第三方。


寫代碼不重構,就和考完試不把做錯的題重新做一遍一樣。

對於考試,如果考試完了不把錯的題做一遍,不懂的還是不懂,你下次考還是會錯。

對於代碼的框架設計,如果寫完代碼不重構,就不會對現有的框架有改進。下次設計框架,要麼設計一個沒有進步的東西,要麼設計一個沒有驗證過只是覺得會有改進的東西。


在項目進入迭代早期,為了快速滿足項目功能上的需求,在項目的擴展性,可維護性上會有折扣。

所以到了閉環內,需求相對固化的階段,重構是在保證業務功能不變的情況下,進行可維護性,擴展性,健壯性的開發行為。


1.需要重構,看著大量重複的代碼、不優雅的設計等等,真的想把他改掉,怕留下來丟人。

2.願意重構,重構需要投入時間和精力,這需要我們的決心。

PS:最近做的一個項目就是如此,同時也是自己做的第一個項目,很糾結。


看完重構一書的總結

《重構》一書經典總結(一) - 世上只有一種英雄主義 - CSDN博客


《禪與摩托車維修藝術》一書中說:

每一部摩托車都有屬於它自己的聲音和節奏,都有它自己的個性,培養車子的個性正是維修保養的真正目的。

你的程序也像一輛摩托車,它也有自己的個性,它正是靠持續重構培養出來的。


簡要回答下自己的感受,

畢竟代碼是給人看的,重構一大作用就是讓原先快速開發後的複雜代碼變得簡化,讓人更好理解。

另外就是為了應對業務需求變化,讓代碼更好擴展。


是噠,而且總會有傻逼的PM你妹的改需求,老大總是會催命一樣,能不需要嗎


我並不想說重構能夠解決軟體中所有的問題,它不是「銀彈」。然而重構是非常有價值的工具,它是你可以用來很好地控制代碼的「銀鉗子」。重構能夠,也應該,被用來完成軟體上的諸多目標。

重構能改善軟體設計

重構使軟體更易理解

重構有助於找到Bug

重構有助於提高編程速度

重構,企業級應用的聖經 這裡有一系列講重構的,共享下~~


因為在軟體開發的過程,我們不可能重新從基本的10開始去寫,而是在無數的已經有的運行代碼去構造和添加。這是個講效率的時代了。孩子,不要問這麼傻的問題了


提高軟體的可維護性,可擴展性。


屋子亂了要打掃,文件多了要整理,功能多了要重構


推薦閱讀:

TAG:軟體開發 | 重構 |