重構(gòu)——代碼的壞味道

如果是尿布抽了咆蒿,就換掉它癞蚕。 —— Beck奶奶

3.1 Duplicated Code

最單純的Duplicated Code是同一個類的兩個函數(shù)含有相同的表達(dá)式妈拌;另一種常見的情況就是兩個互為兄弟的子類內(nèi)含相同的表達(dá)式迟杂,構(gòu)筑超類或者使用模板方法;如果兩個毫不相關(guān)的類出現(xiàn)Dulicated Code缀蹄,提取獨立類峭跳。

3.2 Long Method

擁有短函數(shù)的對象會獲得比較好、比較長袍患。間接層所能帶來的全部利益——解釋能力坦康、共享能力竣付、選擇能力——都是由小型函數(shù)支持的诡延。

3.3 Large Class

如果單個類想做太多的事情,期內(nèi)往往會有太多的實例變量古胆。這往往意味著Duplicated Code肆良。

3.4 Long Parameter List

太長的參數(shù)無法理解,太多的參數(shù)同時也會容易造成前后不一致逸绎。

3.5 Divergent Change(發(fā)散式修改)

我們希望軟件能夠更容易被修改惹恃。如果某個類經(jīng)常因為不同的原因在不同的方向上發(fā)生變化。最好能將類切開棺牧,這也是遵循單一職責(zé)原則巫糙。

3.6 Shotgun Surgery(散彈式修改)

Shotgun Surgery和Divergent Change類似,但是恰恰相反颊乘。如果每遇到某種變化参淹,你都必須在許多不同類內(nèi)做出許多小修改。
  總之乏悄,Divergent Change是指一個類受多種變化影響浙值。Shortgun Surgery則是指一個變化引起多個類相應(yīng)修改。

3.7 Feature Envy(依戀情節(jié))

對象技術(shù)的全部要點在于:這是一種“將數(shù)據(jù)和對數(shù)據(jù)的操作行為包裝在一起”的技術(shù)檩小。有一種經(jīng)典的氣味:函數(shù)對某個類的興趣搞過對自己所處類的興趣开呐。例如:某個類為了計算某個值,從某個類中獲取幾乎半打的取值函數(shù)规求。這種函數(shù)筐付,應(yīng)該將這個函數(shù)移動到它應(yīng)該在的地方。
判斷類的地址的原則:判斷哪個類擁有最多被此函數(shù)使用的數(shù)據(jù)阻肿,然后該函數(shù)就乖乖去了那里瓦戚。Strategy和Visitor就是對抗Divergent Change。最根本的原則:將總是一起變化的東西放在一起冕茅,保持變化永遠(yuǎn)只在一處發(fā)生伤极。當(dāng)然蛹找,你不得不多加一層抽象層次。

3.8 Data Clumps

數(shù)據(jù)項就像小孩子哨坪,喜歡成群結(jié)隊地待在一塊兒庸疾。常常可以在很多地方看到相同的三四項數(shù)據(jù):兩個類中的相同字段当编、許多函數(shù)簽名中的參數(shù)届慈。這些總是綁定在一起出現(xiàn)的數(shù)據(jù)真應(yīng)該擁有屬于它們自己的對象。
  一個好的評判方法:刪除眾多數(shù)據(jù)中的一項忿偷。這么做金顿,其他數(shù)據(jù)沒有失去意義?如果不再有意義鲤桥,這就是明確的意義揍拆,告訴你應(yīng)該為他們產(chǎn)生一個新對象。

3.9 Primitive Obsession(基本類型偏執(zhí))

大多數(shù)編程環(huán)境都有兩種數(shù)據(jù):結(jié)構(gòu)類型允許你將數(shù)據(jù)組織成有意義的形式茶凳;基本類型則是構(gòu)筑結(jié)構(gòu)類型的積木塊嫂拴。結(jié)構(gòu)總是會帶來一定的額外開銷。他們可能代表著數(shù)據(jù)中的表贮喧,如果僅僅為了做一兩件事而穿件結(jié)構(gòu)類型也可能顯得太麻煩了筒狠。

3.10 Switch Statement(驚悚的switch)

面向?qū)ο蟪绦虻囊粋€最棉線特征就是:少用switch(或case)語句。
  大多數(shù)的時候箱沦,一看到switch語句辩恼,你就應(yīng)該考慮以多態(tài)來替代它;但是在單一函數(shù)中有些選擇事例谓形,且并不想改動它們灶伊,那么多態(tài)就有點殺雞用牛刀了。

3.11 Parallel Inheritance Hierarchies(平行繼承體系)

其實是Shotgun Surgery的特殊情況套耕。即一個類增加一個子類谁帕,另一個類也必須增加一個子類。
  一般則略:讓一個繼承體系的實例引用另一個體系的實例冯袍。

3.12 Lazy Class(冗余類)

如果一個類不值其身價匈挖,它就應(yīng)該消失。

3.13 Speculative Generality(夸夸其談未來性)

因為主觀臆測的未來性(未來某天我們需要做這件事情)康愤,并其余以各種各樣的鉤子和特殊情況來處理一些非必要的事情儡循。
  注意:當(dāng)函數(shù)或者類的唯一用戶是測試用例,壞味道就飄出來了征冷。

3.14 Temporary Field(令人迷惑的臨時字段)

對象內(nèi)某個實例變量僅為某特定情況而設(shè)择膝。這樣的代碼會讓讓人無法理解,通常認(rèn)為對象在所有時候都需要它所有變量检激。猜測變量的用途會讓人crazy肴捉。

3.15 Message Chain(過度偶爾得消息鏈)

如果你可以看到用戶向一個對象請求另一個對象腹侣,然后再向后者請求另一個對象,然后再請求另一個對象……這就是消息鏈齿穗。采取這種方式傲隶,意味著用戶代碼將與查找過程中的導(dǎo)航結(jié)構(gòu)緊密耦合。一旦對象間的關(guān)系發(fā)生任何變化窃页,客戶端也的變化跺株。
  可以使用消息隊列模式來進(jìn)行重構(gòu)。

3.16 Middle Man

對象的基本特征之一就是封裝——對外部空間隱藏起內(nèi)部實現(xiàn)細(xì)節(jié)脖卖。封裝也代表著委托乒省。但是也有時候會成為過度的委托。我們會看到某個類接口將其一半的實現(xiàn)委托給其他類畦木。

3.17 Inappropriate Intimacy(狎昵關(guān)系)

有時你會看到兩個類過于親密袖扛,花費太多時間探究彼此的private成分。過分狎昵必須分開馋劈。集成往往造成過度親密攻锰,因為子類對超類的了解總是超過后者的主觀愿望晾嘶。需要的時候妓雾,讓類離開類繼承關(guān)系鏈。

3.18 Alternative Classes with Diffierent Interaces(異曲同工的類)

如果兩個函數(shù)做同一件事情垒迂,卻有著不同的簽名械姻,請根據(jù)用于合并和修改。

3.19 Incomplete Library Class(不完美的庫類)

復(fù)用被視為對象的終極目的机断。不過楷拳,往往復(fù)用的意義經(jīng)常被高估——大多數(shù)對象只要夠用就好。有時候需要根據(jù)需要修改類庫吏奸。

3.20 Data Class(純稚的數(shù)據(jù)類)

Data Class是指它們擁有一些字段欢揖,以及用于訪問(讀寫)這些字段的函數(shù),除此之外一無長處奋蔚。這種類往往被其他類過分操縱她混。這些類可能擁有public字段,果真如此泊碑,需要在別人注意到之前封裝起來坤按;如果這些類內(nèi)含容器類的字段,你應(yīng)該前叉它們是否得到了恰當(dāng)?shù)姆庋b馒过。如果沒有則正確封裝它們臭脓。然后找出取值/設(shè)值函數(shù)被其他類運用的地點。嘗試以Move Method將調(diào)用行為移動到Data Class中腹忽。

3.21 Refused Bequest(被拒絕的遺贈)

子類應(yīng)該繼承超類的函數(shù)和數(shù)據(jù)来累。但是如果不想繼承所有砚作,怎么選擇其中一部分。這就意味著繼承體系設(shè)計錯誤嘹锁。給子類設(shè)計兄弟類偎巢,下移動一部分字段到兄弟類中。從而正確構(gòu)建體系兼耀。

3.22 Comments(過多的注釋)

Comments本身是帶著香味压昼,然而不恰當(dāng)?shù)淖⑨屖窍喈?dāng)臭氣味。只有當(dāng)不知道如何重構(gòu)的時候瘤运,使用注釋才是優(yōu)質(zhì)的方式窍霞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拯坟,隨后出現(xiàn)的幾起案子但金,更是在濱河造成了極大的恐慌,老刑警劉巖郁季,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冷溃,死亡現(xiàn)場離奇詭異,居然都是意外死亡梦裂,警方通過查閱死者的電腦和手機(jī)似枕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來年柠,“玉大人凿歼,你說我怎么就攤上這事∪吆蓿” “怎么了答憔?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長掀抹。 經(jīng)常有香客問我虐拓,道長,這世上最難降的妖魔是什么傲武? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任蓉驹,我火速辦了婚禮,結(jié)果婚禮上谱轨,老公的妹妹穿的比我還像新娘戒幔。我一直安慰自己,他們只是感情好土童,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布诗茎。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪敢订。 梳的紋絲不亂的頭發(fā)上王污,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機(jī)與錄音楚午,去河邊找鬼昭齐。 笑死,一個胖子當(dāng)著我的面吹牛矾柜,可吹牛的內(nèi)容都是我干的阱驾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼怪蔑,長吁一口氣:“原來是場噩夢啊……” “哼里覆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缆瓣,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤喧枷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后弓坞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體隧甚,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年渡冻,在試婚紗的時候發(fā)現(xiàn)自己被綠了戚扳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡菩帝,死狀恐怖咖城,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呼奢,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布切平,位于F島的核電站握础,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏悴品。R本人自食惡果不足惜禀综,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望苔严。 院中可真熱鬧定枷,春花似錦、人聲如沸届氢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亡笑。三九已至诞丽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間顷啼,已是汗流浹背荐虐。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工七兜, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人福扬。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓腕铸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铛碑。 傳聞我的和親對象是個殘疾皇子恬惯,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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