自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

異味代碼到底有多糟糕?—衡量代碼異味的影響

開發(fā) 項目管理
前輩曾經(jīng)教導(dǎo)我們,作為開發(fā)人員,我們最主要的職責(zé)就是不要寫爛代碼。除非你是單兵作戰(zhàn)并且只是寫幾行很快就會棄用的Perl腳本而已,否則最重要 的一點,就是你寫的代碼必須易于閱讀和理解。在軟件產(chǎn)品的整個生命周期中,可維護的代碼通常會免除你和你的同事們呆坐在電腦前痛苦絕望的很多時間。

用科學(xué)實驗來衡量哪些代碼異味最難維護。如何處理有異味的代碼?

前輩曾經(jīng)教導(dǎo)我們,作為開發(fā)人員,我們最主要的職責(zé)就是不要寫爛代碼。除非你是單兵作戰(zhàn)并且只是寫幾行很快就會棄用的Perl腳本而已,否則最重要 的一點,就是你寫的代碼必須易于閱讀和理解。在軟件產(chǎn)品的整個生命周期中,可維護的代碼通常會免除你和你的同事們呆坐在電腦前痛苦絕望的很多時間。

然而,導(dǎo)致代碼可讀性差的原因卻不總是那么清晰,這就是為什么像代碼編寫標(biāo)準、準則、代碼模式和編程語言箴言之類的東西存在的原因之一。一條眾所周知的準則是Martin Fowler【1】寫的《重構(gòu)》這本書,書里描述了一系列的代碼異味以及去掉這些異味的重構(gòu)策略。盡管擁有這個無可估價的資源,我們依然面臨挑戰(zhàn)——除了要學(xué)習(xí)很多重構(gòu)策略,還需要決定哪些的優(yōu)先級比較高。顯然,它們不可能同樣重要!我們?nèi)绾蔚弥F(xiàn)在做的代碼重構(gòu)工作會有長期正面效益呢?

問題在于Martin Fowler的重構(gòu)書沒有提及哪些代碼異味是關(guān)鍵的,哪些不是。Fowler他自己也提到,沒有哪個標(biāo)準或指標(biāo)能夠比得上人的直覺。我們作為開發(fā)人員來說 只能依靠直覺和經(jīng)驗去決定是否需要重構(gòu)。這可能是一場噩夢。面對一個有數(shù)千個代碼異味的系統(tǒng),你要從何處入手?除此之外,任何對代碼的改動都可能帶來意向 不到的副作用。就算有高質(zhì)量的自動化測試,修改代碼常常蘊含高風(fēng)險而且代價昂貴。如果知道哪些代碼異味是***破壞性,先把它們處理掉就好了。另外,我們希 望向管理層展示,我們并不是浪費時間在為了寫漂亮代碼而寫漂亮代碼上,而是我們當(dāng)前的努力能夠在未來為項目帶來長期效益。

 【補充】:在軟件開發(fā)領(lǐng)域,代碼中的任何可能導(dǎo)致深層次問題的癥狀都可以叫做代碼異味。

通常,在對代碼做簡短的反饋迭代時,代碼異味會暴露出一些深層次的問題,這里的反饋迭代,是指以一種小范圍的、可控的方式重構(gòu)代碼?;谶@些暴露的問題,人們會進一步的檢查設(shè)計和代碼中是否還存在別的代碼異味,然后再做進一步的重構(gòu)。從負責(zé)重構(gòu)的開發(fā)者的角度來看,代碼異味可以啟發(fā)何時重構(gòu),如何重構(gòu)。因此,可以說代碼異味推動著重構(gòu)的進行。(摘自維基百科)

收集關(guān)于代碼異味的事實

2009年,挪威Simula研究所需要把一個內(nèi)部系統(tǒng)改造成一個新的內(nèi)容管理系統(tǒng)。這個項目被外包給6個Java開發(fā)人員。這個項目被認為是深入研究代碼異味對可維護性造成影響的機會。

在這個項目持續(xù)的三個月中,他們使用了一些工具來衡量代碼異味,每天跟那些開發(fā)人員面談,并且每個開發(fā)人員的Eclipse IDE上都安裝了一個日志記錄工具。這個日志記錄工具不但記錄修改每個文件花了多長時間,而且記錄了花在搜索,瀏覽以及翻閱代碼所花費的時間。 在這個項目過程中,他們使用一個問題追蹤工具登記下那些開發(fā)人員所面臨的問題,然后反向追蹤到那些引起問題的源代碼文件。除此之外,所有的開發(fā)人員都要接 受面談。這個過程中收集到的數(shù)據(jù)遠遠多于常規(guī)的僅僅分析代碼倉庫的方法。以下是所得到的觀察結(jié)果:

觀察結(jié)果1:***類其實很糟糕!

來源:https://simula.no/publications/Simula.simula.1460

“人人都知道”***類是不好的,可是到底不好到什么程度?如下圖所示:

Y軸代表在項目維護期間花費在閱讀修改一個文件上的時間;X軸代表文件的大小。

請注意,閱讀和修改***的文件(1844行代碼)要花的時間是大部分文件(少于600行代碼)的10倍以上。這個文件就是一個***類。另外請注 意,20000秒差不多是5個小時的工作(對于一個文件來說太長了!)。我們還可以看到編輯另一個大文件(大約1400行代碼)沒有花掉很多時間。這個大 文件包含了很多的訪問器和修改器,沒有包含任何邏輯(相對于全能類)。這解釋了為什么開發(fā)人員沒有在上面花太多時間。包含復(fù)雜邏輯的大文件(即全能類)會 顯著影響可維護性。

建議:你應(yīng)該把包含復(fù)雜邏輯的大文件分割成小文件。一個推薦的閾值是將文件大小保持在1000行代碼內(nèi)。

 

觀察結(jié)果2: 數(shù)據(jù)團塊沒有你想得那么糟糕……

來源:https://simula.no/publications/Simula.simula.1456

“數(shù)據(jù)團塊(Data Clump)”是指一些語義上沒有相關(guān)性的方法和變量集合。一般情況下,包含數(shù)據(jù)團塊的文件包含了不同類型的變量,后面跟著一系列的訪問器和修改器。比 如,下圖中Person這個類包含了不直接跟一個人相關(guān)的信息,因此可以被分割成兩個類。Simula的研究人員創(chuàng)建了一個統(tǒng)計模型來解釋代碼異味的出現(xiàn) 是否增加了開發(fā)人員在維護過程中遭遇問題的可能性(他們會記錄維護過程中面臨的所有問題以及那些引起問題的文件)。他們發(fā)現(xiàn),事實上那些包含數(shù)據(jù)團塊的文 件引起維護問題的可能性更低!

建議:不要去管那些數(shù)據(jù)團塊,除非它們包含了其他代碼異味。

 

觀察結(jié)果3: 堅持接口分離原則

Robert C. Martin(Bob大叔)介紹了接口分離原則(ISP)作為 SOLID 原則【2】的一部分。

接口分離原則指出,任何軟件庫的調(diào)用者都不應(yīng)該被強迫依賴于它沒有調(diào)用的方法。接口分離原則把非常龐大的接口分割成更小更加明確的接口,從而使得調(diào)用者只需要知道他們所關(guān)心的方法。

軟件工程的研究者們【3】提出了如何使用代碼量化標(biāo)準去鑒別一些代碼異味。有些商業(yè)工具實現(xiàn)了這些量化標(biāo)準,但是你也可以提出自己的探測策略并且在 工具中實現(xiàn)它們,比如Java中的SonarQube或者.Net中的NDepend。下圖展示了Simula使用的探測策略,這個策略是基于研究員 Radu Marinescu【4】的工作提出的。

這個類的類“接口寬度”(即公開的方法和屬性個數(shù))為10,類的“調(diào)用者”數(shù)目為8,“平均接口用度”(即調(diào)用者所使用的方法或?qū)傩詡€數(shù)除以調(diào)用者數(shù)目)為0.375。根據(jù)這個探測策略,這個類可能違反了接口分離原則.

關(guān)于數(shù)據(jù)團塊的分析同樣涵蓋了違反接口分離原則的文件,結(jié)果發(fā)現(xiàn)當(dāng)一個文件違反了接口分離原則時,它存在問題的概率的概率會增加。

如下圖所示,違反接口分離原則的文件比沒有違反該原則的文件出問題的概率要高(大約30%),這也印證了上述觀點。


建議:分割那些過于寬泛,用途繁多的接口可以減少維護時出現(xiàn)問題的風(fēng)險。

 #p#

觀察結(jié)果4:代碼異味往往成群結(jié)隊出現(xiàn)

來源:https://simula.no/publications/Simula.simula.1508

在同一個實驗中,某些代碼異味表現(xiàn)出在同一個文件中一起出現(xiàn)的趨勢。如下圖所示,識別出來的代碼異味往往出現(xiàn)在同一個文件里。“異味囤積者”本質(zhì)上 就是那些想要囤積所有系統(tǒng)功能的文件。“混亂因素”是那些在文件中引起困惑的代碼異味。另外兩組,“寬泛接口”和“數(shù)據(jù)容器”的含義則是不言自明的。

建議:如果你在一個文件中發(fā)現(xiàn)了某個類型的代碼異味,你大概想要檢查它是否包含其他的“異味小伙伴”。同個文件中的代碼異味組合會增加風(fēng)險,減少可維護性!

長文略讀

就像Fowler所說,我們要追隨自己的直覺,經(jīng)驗和判斷來決定哪些需要重構(gòu),但是下列根據(jù)科學(xué)研究得出的準則可以幫助你來區(qū)分優(yōu)先級:

  1. 分割那些包含過多邏輯的大文件(多于1000行代碼)
  2.  關(guān)鍵不在于重構(gòu)數(shù)據(jù)團塊
  3. 把那些寬泛而用途繁多的接口按照用途來分割成不同接口
  4. 包含某些代碼異味的文件往往同時會有更多的“不受歡迎的小伙伴”,注意識別它們!

快樂地重構(gòu)吧!

引用:

【1】《重構(gòu):改善既有代碼的設(shè)計》

【2】《敏捷軟件開發(fā)(原則模式與實踐) 》

【3】http://sewiki.iai.uni-bonn.de/research/cultivate/tutorial_exploring_smells_and_metrics

【4】http://loose.upt.ro./download/thesis/thesis.zip

補充:常見的代碼異味

  • 重復(fù)代碼: 相同或者相似的代碼存在于一個以上的地方。
  • 長方法: 一個非常長的方法、函數(shù)或者過程。
  • 巨類: 一個非常龐大的類。
  • 太多的參數(shù): 函數(shù)或者過程的冗長的參數(shù)列表使得代碼可讀性和質(zhì)量非常差。
  • 特性依戀: 一個類過度的使用另一個類的方法。
  • 親密關(guān)系: 一個類依賴另一個類的實現(xiàn)細節(jié)。
  • 拒絕繼承: 子類以一種‘拒絕’的態(tài)度,覆蓋基類中的方法,換句話說,子類不想繼承父類中的方法,參考Liskov substitution principle。
  • 冗余類 / 寄生蟲: 一個功能太少的類。
  • 人為的復(fù)雜: 在簡單設(shè)計已經(jīng)滿足需求的時候,強迫使用極度復(fù)雜的設(shè)計模式。
  • 超長標(biāo)識符: 尤其,在軟件工程中,應(yīng)該毫無保留的使用命名規(guī)則來消除歧義。
  • 超短標(biāo)識符: 除非很明顯,一個變量名應(yīng)該反映它的功用。
  • 過度使用字面值: 為提高可讀性和避免編碼錯誤,應(yīng)該使用命名常量。此外,字面值可以且應(yīng)該在可能的情況下,獨立存放于資源文件或者腳本中,在軟件部署到不同區(qū)域時,可以很方便的本地化。(摘自維基百科)

原文鏈接:http://fagblogg.mesan.no/how-bad-is-smelly-code/

譯文鏈接:http://blog.jobbole.com/48521/

責(zé)任編輯:陳四芳 來源: 博樂在線
相關(guān)推薦

2011-05-18 08:55:43

代碼程序員

2020-08-01 16:40:09

代碼語言Python

2016-09-22 16:47:55

iOSAndroidWindows Pho

2019-04-23 11:27:07

2022-04-08 07:52:00

架構(gòu)多機房多活

2019-10-29 15:00:26

12306架構(gòu)高并發(fā)

2015-02-13 13:31:29

2020-07-20 07:55:53

微信支付架構(gòu)

2024-10-22 15:04:15

2017-02-15 15:04:49

2018-04-16 11:34:59

2020-11-20 09:23:01

高可用異地淘寶

2009-06-15 18:20:27

2022-03-28 18:08:50

通信網(wǎng)絡(luò)綠色通信節(jié)能減排

2022-09-23 08:47:01

DMA網(wǎng)卡CPU

2019-08-01 15:06:49

離職成本員工

2024-06-12 09:44:09

2022-03-28 07:15:56

Unsafe框架工具

2023-11-23 13:07:18

代碼Golang

2013-04-28 09:29:38

云計算
點贊
收藏

51CTO技術(shù)棧公眾號