相信大家平時在工作中必定免不了被遺留代碼折磨,想要下決心重構吧,總有各種各樣的理由讓重構難以推行,最后還是拿著舊代碼湊合用。重構是編程的一次變革,它從根本上改變了某些舊有的習慣,因此必然會面對許多阻力,讓不知所以者感到無比的困惑。下面列出的常見重構誤區(qū),你遇見過嗎? 這句話老少相傳,可謂工程智慧的真實寫照,但是這種想法只會滋生得過且過的情緒。 在你編程生涯的早期,一定明白“千里之堤,潰于蟻穴”的道理,并為之而付出過沉重代價。即使一個細微的變化,都會導致軟件在最糟糕的時刻以莫名其妙的方式停止運轉。一朝被蛇咬,十年怕井繩,故而你害怕任何變化的發(fā)生,只要變化不是必須的。然而這只能夠茍延殘喘維持一時。一旦形勢急轉直下,出現(xiàn)的錯誤不得不解決,新的功能需求也不能一拖再拖了。此時你面對的代碼即使是相同的,但實際卻已養(yǎng)成了大患。 許多經(jīng)驗豐富的程序員之所以認可這種觀點,是因為對一些不必要工作“偷工減料”,乃人之常情,是合情合理的。譬如說,如果應用程序已經(jīng)具備優(yōu)越的性能,就無需為了性能對處理器周期耗費心機。類似的投機性設計,通常會用來搪塞那些具有前瞻性的編程觀點,諸如“我們可能會在將來的某一天需要這一特性”。 從這個意義上講,重構需要隨時進行。在重構時,你需要消除冗余代碼,避免投機性設計或預先優(yōu)化。 而對于重構的老手來講,這樣的軟件完全是“金玉其外,敗絮其中”。如果設計有瑕疵,例如拙劣的代碼和糟糕的結構,那么在軟件外部是看不到這些問題的。然而即使應用程序在某個時候能夠正常運行,我們仍然需要對此進行重構,對設計進行優(yōu)化。從這個意義上講,重構堅持在一些不太明顯,但卻具有決定性作用的特征上作文章,例如設計、簡單性,以及改善源代碼的可讀性,便于理解。 重構可以幫助你贏回對代碼的支配權。這對于那些業(yè)已脫離控制的代碼庫而言并非易事,如果不訴諸于重構,那么唯一的解決之道就是徹底地重寫。 編程是一項復雜活動,需要大量的知識積累。某些知識可能很難掌握,而其好處則在于學習一門新的技能絕對是物有所值的。 重構的偉大之處就在于它的簡單。只需了解很小的一套簡單規(guī)則,再加上一個好的工具,邁開重構的第一步簡直就是輕而易舉。與一個高級程序員應該了解的其他技術相比,重構有著最簡單的學習曲線。 學習重構很快就會迎來你的收獲季節(jié)。當然,與世間萬事萬物相同,知識的學習總是“一份耕耘,一份收獲”的。 復雜點兒的說法是“因為重構通常會引入大量的細粒度元素(如方法和類),這種間接的設計會導致性能的損失?!?/span> 讓我們把時鐘往回調一小段,你會發(fā)現(xiàn)這樣的觀點似曾相識,當初在質疑面向對象編程時,就發(fā)出過類似奇怪的聲音。 事實的真相是代碼結構重構與否,在性能上的區(qū)別微乎其微,所以常??梢院雎圆挥?,除非是某些特別的系統(tǒng)。 經(jīng)驗證明,性能總是受制于某一段確定的代碼。在優(yōu)化階段修復它們,可以獲得你需要的性能等級。能夠輕易地識別關鍵代碼是重中之重。減少代碼的重復與數(shù)量,從而使得代碼易于理解,一旦發(fā)生變化,也只會影響到單獨的模塊,這樣的重構極大地改善了優(yōu)化的過程。 具有優(yōu)美結構以及經(jīng)過重構的代碼,在菜鳥的眼里是笨拙而粗陋的。方法是如此的短小,在他們看來簡直言之無物。類顯得不夠重量級,僅僅包含屈指可數(shù)的幾個成員。這樣的代碼看起來簡直就等于沒有嘛。 像類和方法那樣,若要管理大量的元素,則意味著需要處理的復雜度會加大。 這樣的觀點常會引人誤解。事實上,復雜度總是相同的。但重構后的代碼會顯得條理更清晰,結構更合理。 一個占據(jù)主流的論調是重構可以使得你的程序更快。迄今為止并沒有相關的研究可以證明我的看法,但我的經(jīng)驗告訴我存在這樣的情形,這是唯一合乎邏輯的——由于你在整體上具有少量的代碼,極少的重復以及清晰的意圖,因此重構帶來的益處很快就能彰顯無遺,除非你處理的是一些可有可無、也無任何實際意義的小規(guī)模代碼。 在敏捷方法學中,重構是被頻繁提及的關鍵技術之一,因而通常的解釋是,重構只有在遵循敏捷原則的團隊中才能如魚得水。 其實不然,即使你的團隊采取別的開發(fā)方式,但如果是由你來負責管理編碼方式,這時就是運用重構的時機。沒人能阻止你在IDE中使用“Refactor”選項。如果你遵循小步重構,并在編碼過程中定期執(zhí)行,就能達到最佳的重構效果。某些實踐例如嚴格的代碼所有權或瀑布過程,可能會與重構背道而馳。如果你能夠證明重構從編程的視角來看是有意義的,你就可以開始構建你的支撐庫,首先從你的伙伴開始,然后推廣到整個團隊。 經(jīng)理們通常對此深以為然。將重構視為一個獨立的階段,然后將其放在諸如實現(xiàn)階段和測試階段期間,從管理學的角度來看,容易給人一種錯覺,認為重構就是甘特圖的一根線條,可以輕易地將其壓縮時間甚至移走。 事實上,為了成功地執(zhí)行重構,你需要完整地理解整個問題域,了解需求、設計甚至實現(xiàn)階段的細節(jié)。倘若你從一開始就沒有將實施重構的人看作團隊的一份子,也沒有花時間與客戶交流,分析需求和思考設計,你將很難改善最初的團隊構建的內容。 遵循某種模型,則代碼可以通過它在編碼之后得到精化,就像工業(yè)生產(chǎn)過程中提煉出的某種物質那樣,總會帶來一些好處。若是不能切實地理解代碼的意義,則你真正能夠對重構保有信心的只能是一些細微的改進。若在此種情形下,妄圖通過重構使代碼煥然一新,結果很有可能是南轅北轍,適得其反。代碼若與問題域緊密相關,就有可能使得事情變得更加糟糕,最終還會為你的應用程序引入bug。 我想,一些簡單的重構可以在沒有單元測試的情形下進行。重構工具與編譯器自身可以提供一定的安全保障,不至于引入一些簡單的人為錯誤。你也可以采用傳統(tǒng)方式對代碼進行測試,例如使用調試器或者執(zhí)行功能測試。但這些手動的測試方法卻是乏味而不值得信賴的。重構時,代碼比以前對修改更為敏感與脆弱。若要避免不必要的問題,則應添加單元測試放到項目中。在你執(zhí)行每一小步重構時,就能夠及時發(fā)現(xiàn)錯誤。 毫無疑問,你已經(jīng)千百次地被告知,在編寫代碼時一定要添加注釋。作為一種好的編程實踐,這種思想會幫助別人理解你的代碼。這通常意味著編碼的方式是優(yōu)秀的、有序的、專業(yè)的。因此,如果現(xiàn)在有人居然膽敢告訴你注釋未必是一樁好事兒,你一定會大吃一驚。 添加注釋的動機通常與代碼重構一致。你應該竭力提高代碼的可讀性。在早期,編程工具受制于標識符的長度,故而注釋成為了傳達編程涵義的唯一選擇。立足于重構,則要求代碼是自解釋性的,即選擇正確的方法、類、變量以及其他標識符。同時,你應該避免為了相同的目的使用注釋,因為注釋不會被執(zhí)行,且很容易作廢。在每日的編程成為急就章時,總是會忘記更新注釋、文檔、圖示或其他次等級的工件。 “拼音縮寫命名也可以嘛,多熟悉幾天這個部分你就都看得懂了”。 使用那些類似人類的自然語言為變量命名,可以使得代碼簡明易懂。拜托放棄那些拼音首字母,轉而使用別人能夠輕松理解的詞語吧。 |
|
來自: 昵稱32348297 > 《技術文章》