IDEA真厲害,900行"又臭又長"的類重構(gòu),幾分鐘搞定

IDEA真厲害唤锉,900行"又臭又長"的類重構(gòu)世囊,幾分鐘搞定

最近,在對已有項(xiàng)目進(jìn)行擴(kuò)展的時候窿祥,發(fā)現(xiàn)要改動的一個類它長900行茸习,開放了近40個public接口,我流著淚把它給改完了壁肋。

為了防止這樣的慘劇再次發(fā)生在我的身上,我覺得有必要寫一篇博客來讓廣大程序猿同胞知道代碼重構(gòu)的重要性籽慢。

如果你身邊有一個類寫上千行的猿浸遗,一定要把此文轉(zhuǎn)給ta

為什么類不能過長?

IDEA真厲害箱亿,900行"又臭又長"的類重構(gòu)跛锌,幾分鐘搞定

類過長——讀不通,擴(kuò)展不通

  • 讀不通——直接用滾輪滾都得好幾秒届惋,就算是原作者髓帽,時間長了恐怕也難以理清整個類,更不用說是其他的讀者
  • 擴(kuò)展不通——一個類有過多的接口脑豹,會讓擴(kuò)展這個類變得異常困難郑藏,一動千行

類過長——可能有冗余代碼

此時CV工程師打了個冷戰(zhàn)

冗余代碼,就是重復(fù)代碼瘩欺,通常出自使用Ctrl+C必盖,Ctrl+V來生產(chǎn)代碼的CV工程師之手,冗余代碼的危害非常大:

  1. 冗余代碼使方法俱饿、類過長歌粥,不簡潔
  2. 冗余代碼會造成發(fā)散式修改(冗余代碼需要變動時,每一處Ctrl+V都需要修改)

類過長——多半是職責(zé)過多

一個類開放幾十個接口拍埠,絕對存在職責(zé)過多的問題失驶,就像圖中的Tom貓一樣手忙腳亂,一個類的職責(zé)過多也有巨大問題:

  1. 違反設(shè)計(jì)原則——單一職責(zé)原則(單一職責(zé)原則要求一個類只實(shí)現(xiàn)一個職責(zé)枣购,比如一只Tom只做掃地嬉探、擦桌、拖地中的一件事坷虑,而其他事的實(shí)現(xiàn)可以轉(zhuǎn)移給史派克狗或肥胖女傭)甲馋,違反了這個原則會導(dǎo)致發(fā)散式變化、發(fā)散式修改迄损、類過長等代碼問題定躏,還會讓你的類難以擴(kuò)展,甚至?xí)屍渌绦蛟痴J(rèn)為你不專業(yè)
  2. 發(fā)散式變化(指引發(fā)此類修改的地方很多),如果一個類的職責(zé)很多痊远,那它的扇入(調(diào)用者)一定很多垮抗,每個調(diào)用者的修改都有可能讓你這個類不得不隨之修改,也就是發(fā)散式變化就是說不管哪兒出了問題碧聪,你這個類都得遭殃
  3. 發(fā)散式修改(指此類修改引發(fā)修改的地方很多)冒版,相同的,如果一個類職責(zé)很多逞姿,那支撐它實(shí)現(xiàn)的下級辞嗡,即扇出(被調(diào)用方)一定很多,如果此類邏輯發(fā)生變動滞造,所有下級被調(diào)用者可能都得隨之修改续室,也就是發(fā)散式修改就是說你這個類出了問題,不管哪兒都會遭殃
  4. 難以擴(kuò)展:如果你的一個類接口非常多谒养,那它的子類怎么辦挺狰?它的包裝類怎么辦?難道全部都要實(shí)現(xiàn)這么多接口买窟,全部都要承擔(dān)同樣多的職責(zé)嗎丰泊?擴(kuò)展起來真的非常麻煩
  5. 觸發(fā)機(jī)關(guān):【測試之怒】【運(yùn)維之怒】

我已經(jīng)寫了幾千行了,怎么辦始绍?

IDEA真厲害瞳购,900行"又臭又長"的類重構(gòu),幾分鐘搞定

重構(gòu)——抽取冗余代碼

抽取冗余代碼就是將重復(fù)代碼抽取成一個獨(dú)立的方法疆虚,之后再使用這段代碼時就不再需要Ctrl + C苛败,Ctrl + V,而是直接調(diào)用對應(yīng)的方法即可

這樣做也可以縮短原方法径簿,使原方法更加簡潔易懂

更值得一提的是如果這段代碼需要修改罢屈,也只需修改一處,而不是發(fā)散式地到處修改

真是一箭三雕

使用IDEA進(jìn)行冗余代碼的抽取

1.找到重復(fù)代碼

IDEA真厲害篇亭,900行"又臭又長"的類重構(gòu)缠捌,幾分鐘搞定

2.進(jìn)行方法抽取 右鍵->選擇重構(gòu)->抽取->方法 (或者直接使用快捷鍵Ctrl + Alt + m)

IDEA真厲害,900行"又臭又長"的類重構(gòu)译蒂,幾分鐘搞定
IDEA真厲害曼月,900行"又臭又長"的類重構(gòu),幾分鐘搞定

自動檢測出個別重復(fù)代碼的細(xì)微差別柔昼,有些代碼可能只改動一兩個變量哑芹,IDEA會自動檢測出來,并在抽取方法時提醒我們捕透,選擇左側(cè)Accept Signature Change(接受簽名變動)可以使抽取的方法自動替換更多的重復(fù)點(diǎn)

IDEA真厲害聪姿,900行"又臭又長"的類重構(gòu)碴萧,幾分鐘搞定

可以選擇替換掉所有的重復(fù)代碼(竟然有18處)

IDEA真厲害,900行"又臭又長"的類重構(gòu)末购,幾分鐘搞定

3.重構(gòu)——更改方法簽名

如果你對抽取出的方法的名字破喻、參數(shù)、返回值或是修飾符不滿意盟榴,不要使用Ctrl + R 修改曹质,IDEA提供了重構(gòu)方法——更改簽名(快捷鍵Ctrl + F6)

注意:方法的名字指的是方法做了什么,而非怎么去做擎场,最好是 動詞+名詞 格式

比如:Tom.掃地() √

Tom.掃地With掃把() ×

Tom.用掃把掃地() ×

重構(gòu)——轉(zhuǎn)移成員變量+函數(shù)(轉(zhuǎn)移職責(zé))

將不應(yīng)該由自己管理的成員變量和函數(shù)轉(zhuǎn)移出去

那就要考慮兩個問題:該轉(zhuǎn)移誰羽德?轉(zhuǎn)移給誰?

來看一個圖

IDEA真厲害迅办,900行"又臭又長"的類重構(gòu)玩般,幾分鐘搞定
  1. 圖中成員【偏A】被類【A】調(diào)用兩次,而只被它所在的類【過長類】調(diào)用1次礼饱,因而應(yīng)該轉(zhuǎn)移給【A】去管理
  2. 由于函數(shù)【偏A】與成員【偏A】的親密度較高(只調(diào)用了【偏A】),因而應(yīng)與【偏A】共進(jìn)退究驴,同去留镊绪,轉(zhuǎn)移給【A】
  3. 成員【偏B】和函數(shù)【偏B】也是相同道理
  4. 職責(zé)1(函數(shù)【1】和成員【偏職責(zé)1】)和職責(zé)2(函數(shù)【2】和成員【偏職責(zé)2】)由于找不到可轉(zhuǎn)移的合適的類,所以應(yīng)抽取出一個新的類

注意洒忧,先決定移動哪個成員變量蝴韭,然后再決定移動哪個函數(shù)

使用IDEA轉(zhuǎn)移成員變量和函數(shù)

  1. 移動成員變量,鼠標(biāo)選擇成員變量->右鍵->Refactor->Move熙侍,然后選擇轉(zhuǎn)移至哪個類
  2. 移動函數(shù)(與移動成員變量步驟相同)

重構(gòu)——抽取類

當(dāng)你發(fā)現(xiàn)要轉(zhuǎn)移的成員變量和函數(shù)找不到合適的類時(轉(zhuǎn)移職責(zé)卻找不到下家)榄鉴,要想起來,這里是程序世界蛉抓,而我們程序猿就是類和對象的造物主庆尘,是時候創(chuàng)建一個新的類,讓它來替我們分擔(dān)職責(zé)(成員變量和函數(shù))了

使用IDEA抽取類

1.重構(gòu) 選中要搬的成員變量和函數(shù)巷送,右鍵->Refactor->Extract->Delegate(抽取一個委托者驶忌,委托他來管理這部分變量和函數(shù),如果只有變量或只有函數(shù)笑跛,可以抽出參數(shù)對象Paramater Object或方法對象Method Object)

不推薦抽取參數(shù)對象付魔,因?yàn)橐话銋?shù)對象是給參數(shù)多的方法用的(用參數(shù)對象取代一長溜的參數(shù)),而且如果成員變量抽取了也不會影響任何函數(shù)的話飞蹂,那就是無用對象了几苍,不如直接把他們刪除掉

IDEA真厲害,900行"又臭又長"的類重構(gòu)陈哑,幾分鐘搞定

2.為新類起個名妻坝,選個包吧

IDEA真厲害伸眶,900行"又臭又長"的類重構(gòu),幾分鐘搞定

3.注意惠勒,抽取的函數(shù)和成員一定要符合一個原則赚抡,那就是被抽取函數(shù)使用被抽取成員的次數(shù)一定高于剩余函數(shù)的次數(shù),不然違反親密性原則(成員應(yīng)歸于調(diào)用它最多的類纠屋,沒有理由你用的比我多還讓我來管理)

4.一些小問題

由于抽取的函數(shù)直接使用了未抽取的對象而導(dǎo)致重構(gòu)失敗涂臣,涉及到另一個重構(gòu)(使用get方法而非直接使用私有成員變量),使用此重構(gòu)即可解決

IDEA真厲害售担,900行"又臭又長"的類重構(gòu)赁遗,幾分鐘搞定
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市族铆,隨后出現(xiàn)的幾起案子岩四,更是在濱河造成了極大的恐慌,老刑警劉巖哥攘,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剖煌,死亡現(xiàn)場離奇詭異,居然都是意外死亡逝淹,警方通過查閱死者的電腦和手機(jī)耕姊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栅葡,“玉大人茉兰,你說我怎么就攤上這事⌒来兀” “怎么了规脸?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熊咽。 經(jīng)常有香客問我莫鸭,道長,這世上最難降的妖魔是什么横殴? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任黔龟,我火速辦了婚禮,結(jié)果婚禮上滥玷,老公的妹妹穿的比我還像新娘氏身。我一直安慰自己,他們只是感情好惑畴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布蛋欣。 她就那樣靜靜地躺著,像睡著了一般如贷。 火紅的嫁衣襯著肌膚如雪陷虎。 梳的紋絲不亂的頭發(fā)上到踏,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機(jī)與錄音尚猿,去河邊找鬼窝稿。 笑死,一個胖子當(dāng)著我的面吹牛凿掂,可吹牛的內(nèi)容都是我干的伴榔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼庄萎,長吁一口氣:“原來是場噩夢啊……” “哼踪少!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起糠涛,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤援奢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后忍捡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體集漾,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年砸脊,在試婚紗的時候發(fā)現(xiàn)自己被綠了帆竹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡脓规,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出险领,到底是詐尸還是另有隱情侨舆,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布绢陌,位于F島的核電站挨下,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏脐湾。R本人自食惡果不足惜臭笆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望狸捕。 院中可真熱鬧虽抄,春花似錦奔穿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孟岛。三九已至瓶竭,卻和暖如春督勺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斤贰。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工智哀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荧恍。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓瓷叫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親块饺。 傳聞我的和親對象是個殘疾皇子赞辩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容