用JBuilder 2005實現重構之認識重構

yunchat發表於2005-05-18

用JBuilder 2005實現重構之認識重構

  為什麼要重構

   那麼什麼是重構呢?重構就是在不改變軟體現有功能的基礎上,透過調整程式程式碼改善軟體的質量、效能,使其程式的設計模式和架構更趨合理,提高軟體的擴充套件性和維護性。

  也許有人會問,為什麼不在專案開始時多花些時間把設計做好,而要以後花時間來重構呢?要知道一個完美得可以預見未來任何變化的設計,或一個靈活得可以容納任何擴充套件的設計是不存在的。系統設計人員對即將著手的專案往往只能從大方向予以把控,而無法知道每個細枝末節,其次永遠不變的就是變化,提出需求的使用者往往要在軟體成型後,始才開始"品頭論足",系統設計人員畢竟不是先知先覺的神仙,功能的變化導致設計的調整再所難免。所以"測試為先,持續重構"作為良好開發習慣被越來越多的人所採納,測試和重構像黃河的護堤,成為保證軟體質量的法寶。

  

[@more@]透過重構可以達到以下的目標:

  ·持續偏糾和改進軟體設計

  重構和設計是相輔相成的,它和設計彼此互補。有了重構,你仍然必須做預先的設計,但是不必是最優的設計,只需要一個合理的解決方案就夠了,如果沒有重構、程式設計會逐漸腐敗變質,愈來愈像斷線的風箏,脫韁的野馬無法控制。重構其實就是整理程式碼,讓所有帶著發散傾向的程式碼迴歸本位。

  ·使程式碼更易為人所理解

  Martin Flower在《重構》中有一句經典的話:"任何一個傻瓜都能寫出計算機可以理解的程式,只有寫出人類容易理解的程式才是優秀的程式設計師。"對此,筆者感觸很深,有些程式設計師總是能夠快速編寫出可執行的程式碼,但程式碼中晦澀的命名使人暈眩得需要緊握坐椅扶手,試想一個新兵到來接手這樣的程式碼他會不會想當逃兵呢?

  軟體的生命週期往往需要多批程式設計師來維護,我們往往忽略了這些後來人。為了使程式碼容易被他人理解,需要在實現軟體功能時做許多額外的事件,如清晰的排版佈局,簡明扼要的註釋,其中命名也是一個重要的方面。一個很好的辦法就是採用暗喻命名,即以物件實現的功能的依據,用形象化或擬人化的手法進行命名,一個很好的態度就是將每個程式碼元素像新生兒一樣命名,也許筆者有點命名偏執狂的傾向,如能榮此雅號,將深以此為幸。

  對於那些讓人充滿迷茫感甚至誤導性的命名,需要果決地、大刀闊斧地整容,永遠不要手下留情!

  ·幫助發現隱藏的程式碼缺陷

  孔子說過:溫故而知新。重構程式碼時逼迫你加深理解原先所寫的程式碼。筆者常有寫下程式後,卻發生對自己的程式邏輯不甚理解的情景,曾為此驚悚過,後來發現這種症狀居然是許多程式設計師常患的"感冒"。當你也發生這樣的情形時,透過重構程式碼可以加深對原設計的理解,發現其中的問題和隱患,構建出更好的程式碼。

  ·從長遠來看,有助於提高程式設計效率

  當你發現解決一個問題變得異常複雜時,往往不是問題本身造成的,而是你用錯了方法,拙劣的設計往往導致臃腫的編碼。

  改善設計、提高可讀性、減少缺陷都是為了穩住陣腳。良好的設計是成功的一半,停下來透過重構改進設計,或許會在當前減緩速度,但它帶來的後發優勢卻是不可低估的。

  何時著手重構

  新官上任三把火,開始一個全新的專案時,程式設計師往往也會燃起三把火:緊鑼密鼓、腳不停蹄、加班加點,一支聲勢浩大的千軍萬"碼"夾裹著程式設計師激情和扣擊鍵盤的鳴金奮力前行,勢如破竹,攻城掠地,直指"黃龍府"。

  開發經理是這支浩浩湯湯程式碼隊伍的統帥,他負責這支隊伍的命運,當齊恆公站在山頂上看到管仲訓練的隊伍整齊劃一地前進時,他感嘆說"我有這樣一支軍隊哪裡還怕沒有勝利呢?"。但很遺憾,你手中的這支隊伍原本只是散兵遊勇,在前進中招兵買馬,不斷壯大,所以隊伍變形在所難免。當開發經理發覺隊伍變形時,也許就是剋制住攻克前方山頭的誘惑,停下腳步整頓隊伍的時候了。

  Kent Beck提出了"程式碼壞味道"的說法,和我們所提出的"隊伍變形"是同樣的意思,隊伍變形的訊號是什麼呢?以下列述的程式碼症狀就是"隊伍變形"的強烈訊號:

  ·程式碼中存在重複的程式碼

  中國有118 家整車生產企業,數量幾乎等於美、日、歐所有汽車廠家數之和,但是全國的年產量卻不及一個外國大汽車公司的產量。重複建設只會導致效率的低效和資源的浪費。

  程式程式碼更是不能搞重複建設,如果同一個類中有相同的程式碼塊,請把它提煉成類的一個獨立方法,如果不同類中具有相同的程式碼,請把它提煉成一個新類,永遠不要重複程式碼。


  ·過大的類和過長的方法

  過大的類往往是類抽象不合理的結果,類抽象不合理將降低了程式碼的複用率。方法是類王國中的諸侯國,諸侯國太大勢必動搖中央集權。過長的方法由於包含的邏輯過於複雜,錯誤機率將直線上升,而可讀性則直線下降,類的健壯性很容易被打破。當看到一個過長的方法時,需要想辦法將其劃分為多個小方法,以便於分而治之。

  ·牽一毛而需要動全身的修改

  當你發現修改一個小功能,或增加一個小功能時,就引發一次程式碼地震,也許是你的設計抽象度不夠理想,功能程式碼太過分散所引起的。

  ·類之間需要過多的通訊

  A類需要呼叫B類的過多方法訪問B的內部資料,在關係上這兩個類顯得有點狎暱,可能這兩個類本應該在一起,而不應該分家。

  ·過度耦合的資訊鏈

  "計算機是這樣一門科學,它相信可以透過新增一箇中間層解決任何問題",所以往往中間層會被過多地追加到程式中。如果你在程式碼中看到需要獲取一個資訊,需要一個類的方法呼叫另一個類的方法,層層掛接,就象輸油管一樣節節相連。這往往是因為銜接層太多造成的,需要檢視就否有可移除的中間層,或是否可以提供更直接的呼叫方法。

  ·各立山頭幹革命

  如果你發現有兩個類或兩個方法雖然命名不同但卻擁有相似或相同的功能,你會發現往往是因為開發團隊成員協調不夠造成的。筆者曾經寫了一個頗好用的字串處理類,但因為沒有及時通告團隊其他人員,後來發現專案中居然有三個字串處理類。革命資源是珍貴的,我們不應各立山頭幹革命。

  ·不完美的設計

  在筆者剛完成的一個比對報警專案中,曾安排阿朱開發報警模組,即透過Socket向指定的簡訊平臺、語音平臺及客戶端報警器外掛傳送報警報文資訊,阿朱出色地完成了這項任務。後來使用者又提出了實時比對的需求,即要求第三方系統以報文形式向比對報警系統傳送請求,比對報警系統接收並響應這個請求。這又需要用到Socket報文通訊,由於原來的設計沒有將報文通訊模組獨立出來,所以無法複用阿朱開發的程式碼。後來我及時調整了這個設計,新增了一個報文收發模組,使系統所有的對外通訊都複用這個模組,系統的整體設計也顯得更加合理。

  每個系統都或多或少存在不完美的設計,剛開始可能注意不到,到後來才會慢慢凸顯出來,此時唯有勇於更改才是最好的出路。

  ·缺少必要的註釋

  雖然許多軟體工程的書籍常提醒程式設計師需要防止過多註釋,但這個擔心好象並沒有什麼必要。往往程式設計師更感興趣的是功能實現而非程式碼註釋,因為前者更能帶來成就感,所以程式碼註釋往往不是過多而是過少,過於簡單。人的記憶曲線下降的坡度是陡得嚇人的,當過了一段時間後再回頭補註釋時,很容易發生"提筆忘字,愈言且止"的情形。

  曾在網上看到過微軟的程式碼註釋,其詳盡程度讓人歎為觀止,也從中體悟到了微軟成功的一個經驗。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/118026/viewspace-803478/,如需轉載,請註明出處,否則將追究法律責任。

相關文章