02. 代碼的壞味道

目錄

1.Duplicated Code(重複的代碼)

2.Long Method(過長方法)

3.Large Class(過大的類)

4.Long Parameter List(過長參數列)

5.Divergent Change(發散式變化)

6.Shotgun Surgery(霰彈式修改)

7.Feature Envy(依戀情結)

8.Data Clumps(數據泥團)

9.Primitive Obsession(基本類型偏執)

10.Switch Statements(switch驚悚現身)

11.Parallel Inheritance Hierarchies(平等繼承體系)

12.Lazy Class(冗贅類)

13.Speculative Generality(誇誇其談未來性)

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

15.Message Chains(過度耦合的消息鏈)

16.Middle Man(中間轉手人)

17.Inappropriate Intimacy(狎暱關係)

18.Alternative Classes with Different Interfaces(異曲同工的類)

19.Incomplete Library Class(不完美的程序類庫)

20.Data Class(純稚的數據類)

21.Refused Bequest(被拒絕的遺贈)

22.Comments(過多的註釋)


1.Duplicated Code(重複的代碼)

       假設你在一個以上的地點看到同樣的程序結構,那麼當可肯定:設法將它們合而爲一,程序會變得更好

2.Long Method(過長方法)

       針對過長的方法,我們需要進行分解,我們遵循這樣一條原則:每當感覺須要寫註釋來說明代碼的時候。我們就把須要說明的

       東西寫進一個獨立的方法中,並以其意圖(而非實現手法)命名。我們可以對一組甚至短短一行代碼做這件事。哪怕替換後的方法

       調用動作比方法自身還長,只要函數名稱能夠解釋其用途,我們就應該毫不猶豫地那麼做。關鍵不在於函數的長度,而在於函

       數"做什麼"和"如何做"之間的語義距離。

3.Large Class(過大的類)

       說明這個類做太多事情。其內往往就會出現太多instance變量。一旦如此。Duplicated Code也就接踵而至了。

       和"太多實例變量"一樣,類內如果有太多代碼,也是代碼重複、混亂並最終走向死亡的源頭。最簡單的解決方案是把多餘的東

       西消彌於類內部。如果有五個"百行函數",它們之中很多代碼都相同,那麼或許你可以把它們變成五個"十行函數"和十個提煉

       出來的"雙行函數";還可以先確定客戶端如何使用它們,運用抽象接口爲每一種使用方式提煉一個接口

4.Long Parameter List(過長參數列)

       當一個方法有太長的參數時,會使得該參數列難以理解,太多參數會造成前後不一致、不易使用。可以將來自同一個對象的一

       堆數據收集起來,並以該對象替換他們。如果某些數據缺乏合理的對象歸屬,可以製造一個對象參數。

5.Divergent Change(發散式變化)

       我們希望軟件可以更容易被改動——畢竟軟件再怎麼說本來就該是[軟]的。一旦須要改動,我們希望可以找到系統的某一點,僅

       僅在該處做改動。Divergent Change是指[一個class受多種變化的影響]。如果某個類經常因爲不同的原因在不同的方向上發

       生變化,那麼此時將對象分成多個會更好,這麼一來每個對象就可以只因一種變化而需要修改。

6.Shotgun Surgery(霰彈式修改)

       Shotgun Surgery類似Divergent Change。但恰恰相反。假設每遇到某種變化,你都必須在很多不同的class內做出很多小改動

       以響應之。你所面臨的壞味道就是Shotgun Surgery。假設須要改動的代碼散佈四處。你不但非常難找到它們。也非常容易忘記

       某個重要的改動。這種情況下你應該把所有需要修改的代碼放進同一個類,如果眼下沒有合適的類可以安置這些代碼,就創造

       一個。

       Shotgun Surgery是指[一種變化引發多個classes對應改動]。

7.Feature Envy(依戀情結)

       我們會看到某個方法爲了計算某值,從另一個對象那兒調用差點兒一半以上取值方法。這樣最好是將當前對象的方法移動至另

       外一個對象,如果一個方法調用了多個類的多個功能,那麼它究竟該被置於何處呢?我們的原則是:判斷那一個類擁有最多調

       用方法,然後就把這個函數和那些數據擺在一起。

       最根本的原則是:將總是一起變化的東西放在一塊兒。[數據和[引用這些數據]的行爲總是一起變化的。

8.Data Clumps(數據泥團)

       數據項就像小孩子,喜歡成羣結隊地待在一塊兒。你經常能夠在非常多地方看到同樣的三或四個數據項:兩個類中相同的

       字段、很多方法簽名中相同的參數。這些總是綁在一起出現的數據真應該放進屬於它們自己的對象中

9.Primitive Obsession(基本類型偏執)

       大多數編程環境都有兩種數據:結構類型讓你將數據組織成有意義的形式;基本類型則是構成結構型別的積木塊

10.Switch Statements(switch驚悚現身)

       面向對象程序的一個最明顯特徵就是:少用switch(或case)語句。從本質上說,switch語句的問題在於重複。大多數時候,一看

       到switch語句,就應該考慮以多態來替換它,可以將switch語句提煉到一個獨立函數中,再將它搬移到需要多態性的那個類

       裏。

11.Parallel Inheritance Hierarchies(平等繼承體系)

       Parallel Inheritance Hierarchies事實上是Shotgun Surgery的特殊情況。在這樣的情況下。每當你爲某個class添加一個

       subclass,必須也爲其它已實現的兄弟class對應添加一個subclass。消除這種重複性的一般策略是:讓一個繼承體系的實例引

       用另一個繼承體系的實例。

12.Lazy Class(冗贅類)

       你所創建的每個class,都得有人去理解它、維護它,這些工作都是要花錢的。假設一個class的所得不值其身份。它就應該消

       失。

13.Speculative Generality(誇誇其談未來性)

       這個令我們十分敏感的壞味道,命名者是Brian Foote。當有人說“噢,我想我們總有一天須要做這事”並因而企圖以各式各樣的

       掛勾和特殊情況來處理一些非必要的事情,這樣的壞味道就出現了。

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

       有時你會看到這種對象:其內某個 instance 變量僅爲某種特定情勢而設。這種代碼讓人不易理解,由於你通常覺得對象在全部

       時候都須要它的全部變量。在變量未被使用的情況下推測當初其設置目的,會讓你發瘋。可以單獨抽出一個類來存儲這些

       instance 變量和這個變量相關的代碼。

15.Message Chains(過度耦合的消息鏈)

       假設你看到用戶向一個對象索求還有一個對象,然後再向後者索求還有一個對象,然後再索求還有一個對象……這就是

       Message Chain。實際代碼中你看到的可能是一長串getThis()或一長串暫時變量。採取這樣的方式,意味客戶將與查找過程中

       的航行結構緊密耦合。針對這種情況可以先觀察消息鏈最終得到的對象是用來幹什麼的,看看是否可以把使用該對象的代碼提

       煉到一個方法,再把這個方法推入消息鏈。如果這條鏈上的某個對象有多位客戶打算航行此航線的剩餘部分,就加一個函數來

       做這件事。

16.Middle Man(中間轉手人)

       人們可能過度運用delegation。你或許會看到某個class接口有一半的方法都託付給其他class,這樣就可能是過度運用。這時應

       該讓方法和真正負責的對象打交道。

17.Inappropriate Intimacy(狎暱關係)

       有時候你會看到兩個classes過於親熱,花費太多時間去探究彼此的private成分。假設這發生在兩個人之間。我們不必做衛道

       之士;但對於classes,我們希望它們嚴守清規。繼承往往造成過度親熱,由於subclass對superclass的瞭解總是超過

       superclass的主觀願望。假設你認爲該讓這個孩子獨自生活了,請運用Replace Inheritance with Delegation讓它離開繼承體

       系。

18.Alternative Classes with Different Interfaces(異曲同工的類)

       假設兩個方法做同一件事,卻有着不同的簽名式,針對這種case應該根據他們的用途重新命名。

19.Incomplete Library Class(不完美的程序類庫)

 

20.Data Class(純稚的數據類)

       所謂Data Class是指:它們擁有一些字段,以及用於訪問這些字段的方法,除此之外一無長物。

21.Refused Bequest(被拒絕的遺贈)

       Subclasses應該繼承superclass的方法和數據。但假設它們不想或不須要繼承,又該怎麼辦呢?它們得到全部禮物。卻僅僅從

       中挑選幾樣來玩!按傳統說法,這就意味繼承體系設計錯誤。

22.Comments(過多的註釋)

       別操心,我們並非說你不該寫註釋。從嗅覺上說,Comments不是一種壞味道;其實它們還是一種香味呢。我們之所以要在這

       裏提到Comments,由於人們常把它當作除臭劑來使用。經常會有這種情況:你看到一段代碼有着長長的註釋。然後發現,這

       些註釋之所以存在乃是由於代碼非常糟糕。這種情況的發生次數之多。實在令人驚訝。Comments能夠帶我們找到本章先前提

       到的各種壞味道。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章