代码整洁之道 python_代码整洁之道的 7 个方法
可讀的代碼是可維護(hù)的
在這篇短文中,我將介紹一些你可以用來(lái)改進(jìn)你的代碼的方法。本文代碼示例均使用 JavaScript。
我發(fā)現(xiàn)但凡是可讀的代碼必定是可維護(hù)的。
作為一名開(kāi)發(fā)人員,我的目標(biāo)是編寫(xiě)高質(zhì)量的代碼。團(tuán)隊(duì)中的每個(gè)開(kāi)發(fā)人員,不管他/她的技術(shù)水平如何,都必須能夠通過(guò)閱讀理解我所寫(xiě)的代碼。代碼的可讀性有助于年輕的開(kāi)發(fā)人員編寫(xiě)代碼時(shí)更加自信。
刪除 不必要的 代碼注釋
當(dāng)然,有些代碼可以非常復(fù)雜。我深知這一點(diǎn)且見(jiàn)過(guò)很多次。在復(fù)雜的代碼中,我會(huì)寫(xiě)些適當(dāng)?shù)奈臋n和代碼注釋。
別誤會(huì)。我不是代碼注釋或 JavaScript JSdoc 的愛(ài)好者,而且基本上我能不用它們便不用。
我不需要任何注釋來(lái)解釋這個(gè)接收 X 個(gè)數(shù)組并將它們合并到一個(gè)新的數(shù)組中的函數(shù)。
function mergeArrays(...arrays) {
let mergedArray = []
arrays.forEach(array => {
mergedArray = [...mergedArray, ...array]
})
return mergedArray
}
像示例代碼,如果增添文檔并不能提高可讀性。我希望團(tuán)隊(duì)成員知道展開(kāi)操作符是什么。如果他們不清楚,他們應(yīng)該在代碼審查 code review 時(shí)來(lái)問(wèn)我。
當(dāng)然,我們不要忘記注釋的代碼塊。如果我們忘記了,這里只有一個(gè)解決方案:刪除代碼。既然了不起的 git 可以檢出舊代碼,那么為什么還要把它留在注釋中呢?
請(qǐng)停止把你的代碼庫(kù)變成垃圾場(chǎng)。
重視命名
如果你看到函數(shù)名 mergeArrays,就應(yīng)該很清楚地知道這是一個(gè)將 X 個(gè)數(shù)組組合成一個(gè)新的數(shù)組的函數(shù)。
我知道命名是件難事。函數(shù)越復(fù)雜,命名就越難… 我有個(gè)法子讓命名更容易,舉個(gè)例子:有一個(gè)函數(shù),它會(huì)合并兩個(gè)數(shù)組并生成一個(gè)新的唯一的數(shù)字列表。你會(huì)怎么命名?是下面這樣嗎?
function mergeNumberListIntoUniqueList(listOne, listTwo) {
return [...new Set([...listOne, ...listTwo])]
}
mergeNumberListIntoUniqueList 這個(gè)名字并沒(méi)有那么糟糕,至少功能如其名。命名的難點(diǎn)在于這個(gè)函數(shù)要做兩件事:一個(gè)函數(shù)做的事情越多,命名它就越困難。將這個(gè)函數(shù)拆分為兩個(gè)單獨(dú)的函數(shù),命名會(huì)更容易且函數(shù)復(fù)用更容易。
function mergeLists(listOne, listTwo) {
return [...listOne, ...listTwo]
}
function createUniqueList(list) {
return [...new Set(list)]
}
當(dāng)然,不需要調(diào)用新函數(shù)就可以很容易地創(chuàng)建美觀的一行代碼。但有時(shí),一行代碼的可讀性并不高。
If 語(yǔ)句
我對(duì)這個(gè)問(wèn)題的命名無(wú)力… 看!命名不易…
但我經(jīng)常看到這種情況。
問(wèn)題
if(value === 'duck' || value === 'dog' || value === 'cat') {
// ...
}
解決方法
const options = ['duck', 'dog', 'cat'];
if (options.includes(value)) {
// ...
}
這樣做,你創(chuàng)建了一段像是英語(yǔ)句子般的可讀代碼。
如果選項(xiàng)包含值,那么 ...
提前退出機(jī)制
這個(gè)準(zhǔn)則有很多種命名方式,但我選擇了 “提前退出 Early exit” 這個(gè)名字。
讓我給你們看一段代碼。我相信你們以前見(jiàn)過(guò)這樣的東西。
function handleEvent(event) {
if (event) {
const target = event.target;
if (target) {
// Your awesome piece of code that uses target
}
}
}
來(lái)我們檢查下對(duì)象 event 是否為真,以及屬性 target 是否可用。問(wèn)題是上面代碼我們已經(jīng)用了兩個(gè) if 語(yǔ)句。
讓我們看看如何在這里實(shí)現(xiàn) “提前退出”。
function handleEvent(event) {
if (!event || !event.target) {
return;
}
// Your awesome piece of code that uses target
}
在這里用 “提前退出”,你可以檢查是否 event 和 event.target 同時(shí)非假 。很明顯,我們確信這一事件 event.target 非假。因?yàn)槿绻@個(gè)語(yǔ)句為假,程序就不會(huì)執(zhí)行其他代碼。
解構(gòu)賦值
在 JavaScript 中,我們可以解構(gòu)數(shù)據(jù)和對(duì)象。
根據(jù) developer.mozilla.org 上的文檔,解構(gòu)賦值語(yǔ)法是一種 JavaScript 表達(dá)式。通過(guò)解構(gòu)賦值,可以將值從數(shù)組、屬性從對(duì)象中取出,賦值給其他變量。
一些代碼示例
// Destructuring an object
const numbers = {one: 1, two: 2};
const {one, two} = numbers;
console.log(one); // 1
console.log(two); // 2
// Destructuring an array
const numbers = [1, 2, 3, 4, 5];
const [one, two] = numbers;
console.log(one); // 1
console.log(two); // 2
解構(gòu)的問(wèn)題在于,它有時(shí)會(huì)為屬性創(chuàng)建一個(gè)不好的命名。最好的例子是從 API 獲取數(shù)據(jù)并接收具有 data 屬性的響應(yīng)對(duì)象。
const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)
const {name} = response.data
這個(gè)代碼示例說(shuō)明你正在獲取 id 為 1 的 organizer。organizer 對(duì)象有一個(gè)名字,你可以解構(gòu)它。這樣做沒(méi)什么問(wèn)題。
這段代碼可以正常運(yùn)行。但是為什么屬性名還是 name? 那將是整個(gè)范圍中唯一的 name 屬性嗎?屬性名又來(lái)自哪個(gè)對(duì)象?
通過(guò)重命名屬性可避免這些問(wèn)題。
const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)
const {name: organizerName} = response.data
這段代碼變得更具可讀性。每個(gè)人都知道變量是 organizer 的名字。
童子軍規(guī)則
聽(tīng)過(guò)這樣一句話嗎:“永遠(yuǎn)保持離開(kāi)時(shí)的露營(yíng)地比你發(fā)現(xiàn)它時(shí)更整潔”?
這就是童子軍的規(guī)則。讓代碼比發(fā)現(xiàn)時(shí)更好。你發(fā)現(xiàn)代碼異味 code smell?重構(gòu)它!你發(fā)現(xiàn)一個(gè)未使用的變量?刪除它!
我喜歡把童子軍規(guī)則和打掃房間的情況進(jìn)行類(lèi)比。想象一下,你家里的每個(gè)人都把盤(pán)子放在水槽上,把所有垃圾都放在走廊上,把所有要洗的衣服都放在浴室里。但是每個(gè)星期天,你必須花費(fèi) 4 個(gè)多小時(shí)清理整個(gè)房子。你會(huì)鐘意嗎?
我肯定答案是 NO。所以如果每個(gè)人都立即清理房間的小部分,星期天的工作量會(huì)小一些。
代碼庫(kù)同理。如果每個(gè)小的代碼異味 code smell 都留在代碼庫(kù)中,沒(méi)有人刪除未使用的變量,linter 就會(huì)抓狂且有大約 77 個(gè) warning。而且代碼庫(kù)將會(huì)有很多清潔工作要做,但是如果每個(gè)人都承擔(dān)起自己的責(zé)任并遵守童子軍法則,很多問(wèn)題將會(huì)得到解決。
代碼風(fēng)格
同樣重要的還有確定團(tuán)隊(duì)中的代碼風(fēng)格。
我不 care 你是喜歡單引號(hào)還是雙引號(hào),空格還是 tab,結(jié)尾逗號(hào)還是不用。選擇一種風(fēng)格并堅(jiān)持下去。你可以用 Linter 或者 Prettier 來(lái)做這件事。
有很多工具可以用來(lái)解決代碼風(fēng)格問(wèn)題。我最鐘意的是使用 Husky 預(yù)提交鉤子。Prettier 的文檔中也有一個(gè)關(guān)于預(yù)提交鉤子的頁(yè)面。
這個(gè)預(yù)提交鉤子總是在每次提交之前運(yùn)行配置好的命令。如果你正確地配置它,它會(huì)運(yùn)行得更漂亮,并對(duì)所有文件應(yīng)用所有規(guī)則。這確保了團(tuán)隊(duì)總是擁有統(tǒng)一的代碼風(fēng)格,而沒(méi)有任何糟糕的代碼。
小結(jié)
我知道有些方法顯而易見(jiàn),有些則不是。但作為一名全職開(kāi)發(fā)人員,我在不同的代碼庫(kù)上工作。這些規(guī)則的重要性只有在較大的代碼庫(kù)中才會(huì)突顯。但這并不意味著你不應(yīng)該將這些方法用在小項(xiàng)目中,提高你的代碼質(zhì)量讓小項(xiàng)目更高效。它讓團(tuán)隊(duì)成員方便地閱讀你的代碼并合并你的 pull 請(qǐng)求。正如我所說(shuō)的,可讀的代碼更容易維護(hù),當(dāng)然可讀的代碼還有其他更多的好處。
如果你想了解更多關(guān)于代碼整潔之道的知識(shí),可以嘗試閱讀羅伯特?馬丁的《代碼整潔之道》。
最后,歡迎優(yōu)秀的你加入 HelloGitHub 的「譯文亦舞」系列,讓你的才華舞動(dòng)起來(lái)!把優(yōu)秀的文章分享給更多的人。要求:
平時(shí)瀏覽 GitHub、開(kāi)源、編程、程序員等英文資訊和文章
想把自己閱讀到優(yōu)秀的英文文章分享給更多的人
翻譯準(zhǔn)確但不是直翻或機(jī)翻
保證每月至少翻譯或校正 1 篇高質(zhì)量文章
了解 Markdown 和排版規(guī)則
聯(lián)系我(備注:翻譯和從那個(gè)平臺(tái)來(lái)的)
零基礎(chǔ)學(xué)習(xí)Java編程可以加入我的十年Java學(xué)習(xí)裙:3907814
總結(jié)
以上是生活随笔為你收集整理的代码整洁之道 python_代码整洁之道的 7 个方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: jenkins执行bat失败_关于批处理
- 下一篇: Model、ModelMap和Model