最近在對已有項目進行擴展的時候,發現要改動的一個類它長766行,開放了近40個public接口,我流着淚把它給改完了。爲了防止這樣的慘劇再次發生在個人身上,我以爲有必要寫一篇博客來讓廣大程序猿同胞知道代碼重構的重要性運維
若是你身邊有一個類寫上千行的猿,必定要把此文轉給ta函數
此時CV工程師打了個冷戰測試
冗餘代碼,就是重複代碼,一般出自使用Ctrl+C,Ctrl+V來生產代碼的CV工程師之手,冗餘代碼的危害很是大:設計
一個類開放幾十個接口,絕對存在職責過多的問題,就像圖中的Tom貓同樣手忙腳亂,一個類的職責過多也有巨大問題:cdn
違反設計原則——單一職責原則(單一職責原則要求一個類只實現一個職責,好比一隻Tom只作掃地、擦桌、拖地中的一件事,而其餘事的實現能夠轉移給史派克狗或肥胖女傭),違反了這個原則會致使發散式變化、發散式修改、類過長等代碼問題,還會讓你的類難以擴展,甚至會讓其餘程序猿認爲你不專業對象
發散式變化(指引起此類修改的地方不少),若是一個類的職責不少,那它的扇入(調用者)必定不少,每一個調用者的修改都有可能讓你這個類不得不隨之修改,也就是發散式變化blog
就是說無論哪兒出了問題,你這個類都得遭殃接口
發散式修改(指此類修改引起修改的地方不少),相同的,若是一個類職責不少,那支撐它實現的下級,即扇出(被調用方)必定不少,若是此類邏輯發生變更,全部下級被調用者可能都得隨之修改,也就是發散式修改get
就是說你這個類出了問題,無論哪兒都會遭殃博客
難以擴展:若是你的一個類接口很是多,那它的子類怎麼辦?它的包裝類怎麼辦?難道所有都要實現這麼多接口,所有都要承擔一樣多的職責嗎?擴展起來真的很是麻煩
觸發機關:【測試之怒】【運維之怒】
抽取冗餘代碼就是將重複代碼抽取成一個獨立的方法,以後再使用這段代碼時就再也不須要Ctrl + C,Ctrl + V,而是直接調用對應的方法便可
這樣作也能夠縮短原方法,使原方法更加簡潔易懂
更值得一提的是若是這段代碼須要修改,也只需修改一處,而不是發散式地處處修改
真是一箭三雕
找到重複代碼
進行方法抽取 右鍵->選擇重構->抽取->方法 (或者直接使用快捷鍵Ctrl + Alt + m)
自動檢測出個別重複代碼的細微差異,有些代碼可能只改動一兩個變量,IDEA會自動檢測出來,並在抽取方法時提醒咱們,選擇左側Accept Signature Change(接受簽名變更)可使抽取的方法自動替換更多的重複點
能夠選擇替換掉全部的重複代碼(居然有18處)
重構——更改方法簽名
若是你對抽取出的方法的名字、參數、返回值或是修飾符不滿意,不要使用Ctrl + R 修改,IDEA提供了重構方法——更改簽名(快捷鍵Ctrl + F6)
注意:方法的名字指的是方法作了什麼,而非怎麼去作,最好是 動詞+名詞 格式
好比:Tom.掃地() √
Tom.掃地With掃把() ×
Tom.用掃把掃地() ×
將不該該由本身管理的成員變量和函數轉移出去
那就要考慮兩個問題:該轉移誰?轉移給誰?
來看一個圖
注意,先決定移動哪一個成員變量,而後再決定移動哪一個函數
移動成員變量,鼠標選擇成員變量->右鍵->Refactor->Move,而後選擇轉移至哪一個類
移動函數(與移動成員變量步驟相同)
當你發現要轉移的成員變量和函數找不到合適的類時(轉移職責卻找不到下家),要想起來,這裏是程序世界,而咱們程序猿就是類和對象的造物主,是時候建立一個新的類,讓它來替咱們分擔職責(成員變量和函數)了
重構 選中要搬的成員變量和函數,右鍵->Refactor->Extract->Delegate(抽取一個委託者,委託他來管理這部分變量和函數,若是隻有變量或只有函數,能夠抽出參數對象Paramater Object或方法對象Method Object)
不推薦抽取參數對象,由於通常參數對象是給參數多的方法用的(用參數對象取代一長溜的參數),並且若是成員變量抽取了也不會影響任何函數的話,那就是無用對象了,不如直接把他們刪除掉
爲新類起個名,選個包吧
注意,抽取的函數和成員必定要符合一個原則,那就是被抽取函數使用被抽取成員的次數必定高於剩餘函數的次數,否則違反親密性原則(成員應歸於調用它最多的類,沒有理由你用的比我多還讓我來管理)
一些小問題
因爲抽取的函數直接使用了未抽取的對象而致使重構失敗,涉及到另外一個重構(使用get方法而非直接使用私有成員變量),使用此重構便可解決