影響您的代碼庫的10個(gè)編程代碼味道
在編程成為干凈的代碼忍者時(shí),我們應(yīng)該認(rèn)識(shí)到比較常見的代碼氣味的集合。
您是否曾經(jīng)在閱讀代碼時(shí)感覺到告訴您某些錯(cuò)誤的感覺? 那種"看起來有些不好"的感覺,但是,您仍然無法確切地知道問題出在哪里嗎?
這種怪異的感覺是,您從代碼中得到的是正確的直覺。 這些是不良做法,通常稱為代碼氣味。
能夠發(fā)現(xiàn)氣味并實(shí)現(xiàn)更清潔的解決方案將幫助您在編程生涯中取得重大進(jìn)步,幫助您自學(xué)如何編寫干凈的代碼。
臨時(shí)字段
即使試圖避免這種情況,也有一種常見的情況是我們有條件地設(shè)置一個(gè)類字段。 由于您希望使用類中的所有字段,因此這可能會(huì)使代碼的清晰度降低。
好的解決方案是提取一個(gè)新類,以為此字段創(chuàng)建一個(gè)位置并移動(dòng)相關(guān)功能。 另外,最好引入一個(gè)特殊情況,當(dāng)變量無效時(shí),該情況會(huì)創(chuàng)建另一個(gè)類。
龐大的類
當(dāng)一個(gè)類開始增長并且包含太多字段時(shí),重復(fù)的代碼就在后面。 而且我們討厭重復(fù)的代碼! 因此,我們應(yīng)注意使其盡可能小。
您可能會(huì)發(fā)現(xiàn)自己重構(gòu)了一個(gè)無限類,因?yàn)樗梢蕴幚頍o關(guān)的操作,第一個(gè)解決方案是使用類提取來分離代碼。
但是由于我們喜歡簡單的解決方案,因此最快的解決方案可能是消除類本身內(nèi)部的冗余。 例如,要這樣做,您可以采用帶有大量共享代碼的長方法,然后將它們拆分為較小的方法,以便您可以根據(jù)需要進(jìn)行組合,從而避免任何形式的重復(fù)。
循環(huán)
即使它們長期以來一直是編程的核心,并且仍然有用,但仍有許多替代方法可以幫助我們的代碼更具描述性,并讓我們對(duì)代碼一見鐘情。
使用.map或.filter之類的管道方法有助于立即了解結(jié)構(gòu)的操作方式,從而減少了更強(qiáng)制性的代碼所造成的抽象。
懶元素
有時(shí)我們實(shí)現(xiàn)一個(gè)新結(jié)構(gòu),目的是在以后重用它,或者使我們的代碼更整潔和更具描述性,但是最后,我們意識(shí)到它是無用的,并且我們從未在代碼庫中使用過它。 犧牲這部分代碼!
例如,我們可以對(duì)函數(shù)和類使用內(nèi)聯(lián)技術(shù)來實(shí)現(xiàn)此結(jié)果。
神秘的名字
根據(jù)菲爾·卡爾頓的說法:
在計(jì)算機(jī)科學(xué)中只有兩件難事:緩存無效和命名。
我完全同意他的看法。 正確命名變量,函數(shù)和類可以大大提高代碼的清潔度! 它可以確保描述性更強(qiáng)的代碼,減少注釋的使用,并使將來的開發(fā)人員在閱讀代碼時(shí)更加輕松!
請記住,一臺(tái)機(jī)器可以理解0和1,我們的代碼稍后會(huì)翻譯成該語言。 但是,我們編寫的代碼是為人類編寫的,因此請編寫代碼,就像向6歲的孩子解釋代碼一樣。
全局?jǐn)?shù)據(jù)
這是每個(gè)開發(fā)人員在編寫代碼時(shí)都應(yīng)記住的事情,因?yàn)榭梢詮娜魏蔚胤皆L問(尤其是可變的)代碼,如果修改后會(huì)產(chǎn)生意外的行為。
全局?jǐn)?shù)據(jù)最常見的示例是全局變量。 我們可以使用的第一個(gè)防御機(jī)制是用函數(shù)封裝變量,因?yàn)檫@至少提供了更好的方法來控制其訪問并查看其修改位置。
但是,我建議您始終避免使用全局變量和一般的全局?jǐn)?shù)據(jù)。 始終存在不同的方法來實(shí)施可行的解決方案
注釋過多
我并不是說注釋自己的代碼很不好,但是如果您編寫的程序具有良好的命名并遵循簡潔的代碼模式,則代碼將是不言自明的,從而減少了文件的樣板并提高了代碼庫的可維護(hù)性。
當(dāng)您需要編寫注釋時(shí),請首先嘗試重構(gòu)代碼,以使任何注釋都變得多余。 馬丁·福勒。
長參數(shù)列表
您認(rèn)為期望6-7個(gè)(或更多)參數(shù)的有序列表的函數(shù)不會(huì)引起混淆嗎? 有這么長的列表更容易出現(xiàn)錯(cuò)誤并降低可讀性。
通常,我們可以通過引入?yún)?shù)對(duì)象來解決此問題。 這樣做包括將適合在一起的一長串參數(shù)組合到一個(gè)新對(duì)象中,并將其作為唯一參數(shù)傳遞。 這具有很多好處,因?yàn)槲覀兛梢栽诤瘮?shù)調(diào)用之前定義參數(shù)對(duì)象,而屬性順序無關(guān)緊要。 這是我們在任何參數(shù)列表中都應(yīng)始終考慮的問題。
另一個(gè)選擇是將函數(shù)組合成一個(gè)類,但這通常在某些函數(shù)共享相同的參數(shù)值時(shí)使用,以便我們可以捕獲它們。
重復(fù)的代碼
代碼復(fù)制是非常專業(yè)的代碼庫中存在的另一種常見反模式,我們應(yīng)該盡力減少它,以保持代碼干凈,并避免在功能改變時(shí)在不同位置更改同一代碼。
有多種情況可以幫助刪除重復(fù)的代碼,但是最常見的解決方案是創(chuàng)建一個(gè)新函數(shù)來封裝該邏輯的解決方案,或者在代碼不完全相同的情況下,可以重新排列代碼,以使它們相似 所有項(xiàng)目都在一起以便于提取(Slide語句)。
冗長功能
在我看來,為人類編寫代碼是成為優(yōu)秀程序員的黃金法則。 長函數(shù)是這種思維方式的較大敵人之一,因?yàn)殚L函數(shù)使我們的代碼可讀性降低。
函數(shù)需要描述它們的功能,并應(yīng)專注于一個(gè)孤立的任務(wù),以便我們在必要時(shí)可以重用它們。 通常,隨著功能的變長,其復(fù)雜性也會(huì)隨之增加,并且代碼的可維護(hù)性也會(huì)降低。
在大多數(shù)情況下,解決此問題的方法是將一部分代碼提取到新函數(shù)(提取函數(shù))中,并在必要時(shí)重新使用。
總結(jié)
照顧好您的代碼并努力理解如何進(jìn)行改進(jìn),這使我一直熱愛代碼和編程。 希望您能分享我的看法,并希望您喜歡這篇文章。 我將大部分學(xué)習(xí)歸功于Martin Fowler和他的Refactoring書,我認(rèn)為這是必讀的!