摘要:在敏捷中,讓設計簡單化,必須讓設計從簡單開始,然后變得成熟,要做到這一點,重構是唯一的出路,
本文分享自華為云社區《敏捷技術實踐之重構》,作者:華為云PaaS服務小智 ,
前言
極限編程(XP)的創始人之一Ron Jeffries說道:“在敏捷中,讓設計簡單化,必須讓設計從簡單開始,然后變得成熟,要做到這一點,重構是唯一的出路,”
什么是重構
重構是指改變代碼的結構,而不是代碼的行為,舉個例子:假設一個程式中有兩個方法,每個方法都包含幾行相同的代碼,那么這幾行相同的代碼可以從原來的兩個方法中抽取出來,放到一個新的方法中,在原來放置這幾行代碼的地方替換為呼叫這個新的方法,這個重構稍微改善了程式的可讀性和可維護性,因為現在一些代碼明顯被復用,并且重復的代碼被移到了一個地方,代碼結構發生了改變,但是行為并沒有變,
重構不僅對TDD(測驗驅動開發)的成功至關重要,同時也有助于防止代碼腐爛,代碼腐爛是由重復的代碼、無數的補丁、糟糕的分類和其他編程差異造成的,團隊的開發人員以他們自己的風格撰寫代碼也會導致代碼腐爛,產品發布后,代碼腐爛是典型的綜合癥,如果允許代碼腐爛,過不了幾年,系統就要全部重寫,通過不斷的重構,并且在一些小問題變成大問題之前不斷地修復它們,我們能夠保持我們的應用程式不會腐爛,Robert C.Martin稱之為童子軍規則,
童子軍里有一個規定:“離開的時候,總要讓露營地比你來的時候更干凈,”應用于軟體開發中就是:提交一個模塊代碼的時候,要讓它比下載的時候更簡潔一些,不論誰是這段代碼的原作者,如果我們都遵循這個簡單的規定我們的系統最侄訓變得越來越好,是整個團隊照料整個系統,而非個人各自只關心他們那一小部分,這樣就符合代碼集體所有制原則,同時還可以培養團隊成員的主人翁精神和責任感,
何時重構
Kent Beck提出了“代碼壞味道”的說法,這種壞味道,就是發出了重構的強烈資訊,在《重構》一書中提到了24類,在這里我們重點討論以下幾類:
1.神秘命名
猜謎這件事如果發生在閱讀代碼的時候,就不是一個好的體驗,代碼整潔最重要的一項就是好的命名,盡量做到見名知意,每個團隊都有自己統一的命名規范,常見命名方法有駝峰命名法如userName,蛇形命名法如user_name,脊柱命名法如user-name等,不論哪一種,就是不要出現theList,var1這種寫法,
在代碼撰寫程序中,我們應該深思熟慮如何給函式、模塊、變數和類命名,使他們能夠清晰地表明自己的功能和用法,改名是最常用的重構手段,包括修改函式宣告、變數改名、欄位改名等,好的名字能夠節省未來在猜謎上的大把時間,如果想不出一個好的名字,說明背后很可能潛在更深的設計問題,為一個名字所付出的糾結,常常能推動我們對代碼進行精簡,
2.重復代碼
重復代碼,顧名思義就是兩段代碼看上去幾乎相同或者兩段代碼都是實作相同的功能,當程式中存在大量重復的代碼,會造成代碼長度過長,不易閱讀,遇到相同或相似的代碼段需要仔細分辨,如果需要修改某一處的時候,為了避免遺漏需要查找出所有的相同代碼段進行修改,不易維護,
如果是同一個類的兩個函式含有相同的代碼,如文章開頭的例子,這時候可以用提煉函式來提煉出重復的代碼,然后讓這兩個地點都呼叫被提煉出的那段代碼,如果重復代碼只是相似而不是相同,可以先嘗試用移動陳述句重組代碼順序,把相似的部分放在一起以便于提煉,
3.過長引數串列
函式通常都需要接收引數,然后去完成某些處理,在《代碼整潔之道》中提出,一個函式的引數應該盡可能短,最好只有一個,其次是兩個,如果出現三個以上的引數,就需要注意了,函式的引數過多不易于維護和修改,可讀性也差,容易出錯,
如果一些引數來自同一個物件,那么就不要單獨取出這些數作為函式引數傳遞,而是直接將這個物件傳遞過去,如果某些引數值可以通過呼叫已知的一個方法得到,那么就要把這個引數退換為在方法體內呼叫取值的那個已知方法,還有引數不來自同一個物件,如果有必要,我們也要毫不猶豫的為這些引數新建一個不可變的類,強制將它們放在一起
4.過長函式
在編程早期,由于呼叫子函式需要產生額外的開銷,所以大家都不喜歡小函式,一個函式動輒幾百多行,滑鼠的滾動條要滾好一會才能到方法末尾,更不用說一行一行的去閱讀,去理解,可以想象別人來修改這段代碼的時候他有多么痛苦,現代的開發環境已經完全免除了行程內的函式呼叫開銷,所以要保證自己的函式短小精悍,通常一個函式長度的底線是要在一個螢屏內完全顯示,
當然有時候一個函式開始的時候并不是那么長,只是隨著每次需求的變更,每次一點點的加代碼而沒有注意重構,僥幸的認為一點點根本不算什么,積少成多最后終于不可收拾了,
過長函式應該積極的進行函式分解,提煉函式,找到函式中適合集中在一起的部分,把他們提煉出來形成一個新的函式,哪怕有時候是對一行代碼進行這樣的提取也是值得的行動,因為關鍵不在于函式的長度,而是在于函式做了什么,
5.全域資料
在開始學習編程的時候,老師應該講過避免使用全域變數,因為它太不可控了,在代碼的任何一個角落都可以修改它,而且沒有任何機制能夠探測出來到底哪段代碼做出了修改,全域變數一次次造成的那種詭異bug,足夠讓你刻骨銘心,
對于全域資料要避免使用,函式內的就放在函式體內,代碼段內的就放在代碼段中,無處可放,需要單獨存在的全域資料就將其封裝在函式中,這樣就可以找到在哪個地方進行了修改,還要將這個函式放在某個類中,限定那些方法可以使用它,讓資料的修改程序可控可追溯,
6.注釋
代碼中如果出現了大段的注釋用來解釋代碼的含義,而原因是代碼寫的太糟糕了,不得不依賴于注釋,這就是一種壞味道,
當你感覺需要寫注釋的時候,可以先試試重構,試著讓所有注釋都變得多余,如果需要注釋來解釋一段代碼做了什么,可以試試提煉函式;如果函式已經提煉出來,但是還是需要注釋來解釋做了什么,可以試試為函式宣告改名;如果注釋是說明某些系統的需求規格,試試引入斷言,
不是提倡不要寫注釋,而是要寫合適的注釋,對于注釋,我們應該遵循這樣一條原則:“注釋的使用不是為了說明這段代碼能做什么而是應該說明為什么要這么做”,
7.死代碼
死代碼泛指在程式運行程序中執行不到的代碼,或者執行的到但沒有任何作用的代碼,也就是無用代碼,當程式中的變數變成不依賴于外部傳過來的資料,被定義成常量時,便無法適應外界其他的變化,就會產生死代碼,這些代碼通常是由于需求變更或者代碼修改,變得用不到了,如果發現,就及時清除它們,
寫在最后
重構越晚,需要修改的代碼越多,就會形成技術債務,除了上面提到的幾類重構的場景,還有很多其他的場景,重構雖然不是包治百病的靈丹妙藥,但是重構是非常有價值的,可以幫助你始終良好地控制自己的代碼,尤其是作為敏捷開發團隊,重構是團隊成員應該熟練掌握的,任何團隊都應建立重構技能,同時,Scrum培訓師Stefan Wolpers表示,Scrum團隊應該考慮將15%~20%的資源分配給每個Sprint周期的重構代碼和修復錯誤,由此可見,重構這件事情是循序漸進的作為一項改進活動持續進行,
點擊關注,第一時間了解華為云新鮮技術~
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/538769.html
標籤:其他
上一篇:看問題和做事情
下一篇:要想后期修改少,代碼重構要趁早
