代码坏味道
最近在做項目的代碼重構(gòu)和治理,根據(jù)《重構(gòu)》的定義:
在不改變代碼外在行為的前提下,對代碼做出修改,以改進程序的內(nèi)部結(jié)構(gòu)。
良好的代碼設(shè)計對與后續(xù)維護、改動的作用是不可忽視的。差勁的代碼重構(gòu),幾乎等同于重寫。
1.Duplicated Code(重復的代碼)
壞味道的首當其沖是重復的代碼Duplicated Code。假設(shè)你在一個以上的地點看到同樣的程序結(jié)構(gòu),那么當可肯定:設(shè)法將它們合而為一,程序會變得更好。
最單純的Duplicated Code就是[同一個class內(nèi)的兩個方法含有同樣表達式(expression)]。
2.Long Method(過長方法)
我們遵循這樣一條原則:每當感覺須要寫注釋來說明代碼的時候。我們就把須要說明的東西寫進一個獨立的方法中,并以其意圖(而非實現(xiàn)手法)命名。
3.Large Class(過大的類)
說明這個類做太多事情。其內(nèi)往往就會出現(xiàn)太多instance變量。
一旦如此。Duplicated Code也就接踵而至了。
4.Long Parameter List(過長參數(shù)列)
5.Divergent Change(發(fā)散式修改)
我們希望軟件可以更easy被改動——畢竟軟件再怎么說本來就該是[軟]的。
一旦須要改動,我們希望可以找到系統(tǒng)的某一點,僅僅在該處做改動。
Divergent Change是指[一個class受多種變化的影響]
6.Shotgun Surgery(霰彈式改動)
Shotgun Surgery類似Divergent Change。但恰恰相反。假設(shè)每遇到某種變化,你都必須在很多不同的class內(nèi)做出很多小改動以響應(yīng)之。你所面臨的壞味道就是Shotgun Surgery。假設(shè)須要改動的代碼散布四處。你不但非常難找到它們。也非常easy忘記某個重要的改動。
Shotgun Surgery是指[一種變化引發(fā)多個classes對應(yīng)改動]。
7.Feature Envy(依戀情結(jié))
我們會看到某個方法為了計算某值,從還有一個對象那兒調(diào)用差點兒半打的取值方法。
最根本的原則是:將總是一起變化的東西放在一塊兒。[數(shù)據(jù)]和[引用這些數(shù)據(jù)]的行為總是一起變化的。
8.Data Clumps(數(shù)據(jù)泥團)
數(shù)據(jù)項就像小孩子:喜歡成群結(jié)隊地待在一塊兒。你經(jīng)常能夠在非常多地方看到同樣的三或四個數(shù)據(jù)項:兩個classes內(nèi)的同樣字段、很多方法簽名式中的同樣參數(shù)。這些[總是綁在一起出現(xiàn)的數(shù)據(jù)]真應(yīng)該放進屬于它們自己的對象中。
9.Primitive Obsession(基本類型偏執(zhí))
大多數(shù)編程環(huán)境都有兩種數(shù)據(jù):結(jié)構(gòu)類型讓你將數(shù)據(jù)組織成有意義的形式;基本類型則是構(gòu)成結(jié)構(gòu)型別的積木塊。
10.Switch Statements(switch驚悚現(xiàn)身)
面向?qū)ο蟪绦虻囊粋€最明顯特征就是:少用switch(或case)語句。
11.Parallel Inheritance Hierarchies(平等繼承體系)
Parallel Inheritance Hierarchies事實上是Shotgun Surgery的特殊情況。在這樣的情況下。每當你為某個class添加一個subclass,必須也為其它已實現(xiàn)的兄弟class對應(yīng)添加一個subclass。
12.Lazy Class(冗贅類)
你所創(chuàng)建的每個class,都得有人去理解它、維護它,這些工作都是要花錢的。
假設(shè)一個class的所得不值其身份。它就應(yīng)該消失。
13.Speculative Generality(夸夸其談未來性)
這個令我們十分敏感的壞味道,命名者是Brian Foote。當有人說“噢,我想我們總有一天須要做這事”并因而企圖以各式各樣的掛勾和特殊情況來處理一些非必要的事情,這樣的壞味道就出現(xiàn)了。
14.Temporary Field(令人迷惑的臨時字段)
有時你會看到這種對象:其內(nèi)某個instance 變量僅為某種特定情勢而設(shè)。這種代碼讓人不易理解,由于你通常覺得對象在全部時候都須要它的全部變量。在變量未被使用的情況下推測當初其設(shè)置目的,會讓你發(fā)瘋。
15.Message Chains(過度耦合的消息鏈)
假設(shè)你看到用戶向一個對象索求還有一個對象,然后再向后者索求還有一個對象,然后再索求還有一個對象……這就是Message Chain。實際代碼中你看到的可能是一長串getThis()或一長串暫時變量。採取這樣的方式,意味客戶將與查找過程中的航行結(jié)構(gòu)緊密耦合。
16.Middle Man(中間轉(zhuǎn)手人)
人們可能過度運用delegation。你或許會看到某個class接口有一半的方法都托付給其他class,這樣就可能是過度運用。
17.Inappropriate Intimacy(狎昵關(guān)系)
有時候你會看到兩個classes過于親熱,花費太多時間去探究彼此的private成分。假設(shè)這發(fā)生在兩個[人]之間。我們不必做衛(wèi)道之士;但對于 classes,我們希望它們嚴守清規(guī)。
繼承往往造成過度親熱,由于subclass對superclass的了解總是超過superclass的主觀愿望。假設(shè)你認為該讓這個孩子獨自生活了,請運用Replace Inheritance with Delegation讓它離開繼承體系。
18.Alternative Classes with Different Interfaces(異曲同工的類)
假設(shè)兩個方法做同一件事,卻有著不同的簽名式。
19.Incomplete Library Class(不完美的程序類庫)
20.Data Class(純稚的數(shù)據(jù)類)
所謂Data Class是指:它們擁有一些字段,以及用于訪問這些字段的方法,除此之外一無長物。
21.Refused Bequest(被拒絕的遺贈)
Subclasses應(yīng)該繼承superclass的方法和數(shù)據(jù)。但假設(shè)它們不想或不須要繼承,又該怎么辦呢?它們得到全部禮物。卻僅僅從中挑選幾樣來玩!
按傳統(tǒng)說法,這就意味繼承體系設(shè)計錯誤。
22.Comments(過多的注釋)
別操心,我們并非說你不該寫注釋。
從嗅覺上說,Comments不是一種壞味道;其實它們還是一種香味呢。
我們之所以要在這里提到Comments,由于人們常把它當作除臭劑來使用。
經(jīng)常會有這種情況:你看到一段代碼有著長長的注釋。然后發(fā)現(xiàn),這些注釋之所以存在乃是由于代碼非常糟糕。這種情況的發(fā)生次數(shù)之多。實在令人驚訝。
Comments能夠帶我們找到本章先前提到的各種壞味道。
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
- 上一篇: 贪心算法和动态规划
- 下一篇: Elasticsearch(二)概念及安