代碼中到底應(yīng)不應(yīng)當(dāng)寫(xiě)注釋?zhuān)?/h1>
更新時(shí)間:2014年10月08日 09:18:01 投稿:hebedich
注釋的確有其用途,但大部分情況下,程序員在濫用注釋。我是反對(duì)夾雜在代碼間的注釋的,我認(rèn)為注釋?xiě)?yīng)當(dāng)從代碼中獨(dú)立出來(lái)——通常被稱(chēng)為文檔。
當(dāng)很多前輩教育后輩應(yīng)當(dāng)多寫(xiě)注釋的時(shí)候,當(dāng)網(wǎng)絡(luò)上充滿了有關(guān)程序員從不寫(xiě)注釋的段子的時(shí)候,這是一個(gè)非常有爭(zhēng)議的話題。作為一個(gè)標(biāo)題黨,容我先修正一下我的觀點(diǎn):我認(rèn)為如果代碼寫(xiě)得足夠好,那么大多數(shù)注釋是多余的,我們應(yīng)該通過(guò)寫(xiě)出更好的代碼來(lái)代替更多注釋。
注釋的確有其用途,但大部分情況下,程序員在濫用注釋。我是反對(duì)夾雜在代碼間的注釋的,我認(rèn)為注釋?xiě)?yīng)當(dāng)從代碼中獨(dú)立出來(lái)——通常被稱(chēng)為文檔。
請(qǐng)看下面一段代碼。
復(fù)制代碼 代碼如下:
/* /static/market/checkout.js
2014.7.2 create by orzfly
2014.7.29 update by jysperm: fixbugs
TODO: 這段代碼中注釋太多了,需要移除一些 -- jysperm
*/
var raw_products = req.query['products'].split(',');
// 商品 ID 的數(shù)組
var products = []
// 過(guò)濾每個(gè)參數(shù)
for(var i = 0, i < raw_products.length, i++) {
if (!raw_products[i])
return;
// 前端傳來(lái)的數(shù)據(jù)中居然會(huì)有空格
if (!raw_products[i].trim())
return
/* 2014.7.22: 現(xiàn)在可以使用非數(shù)字 ID 了
// 略過(guò)非數(shù)字條目
if (isNan(raw_products[i].trim().toFixed()))
return;
*/
products.push(raw_products[i].trim().toFixed());
}
// 總錢(qián)數(shù)
var sum = 0;
// 計(jì)算每個(gè)商品的總錢(qián)數(shù)
for(var i = 0, i < products.length, i++) {
// 從數(shù)據(jù)庫(kù)中查商品信息
var data = db.product.byID(products[i]);
// TODO: 誰(shuí)來(lái)寫(xiě)一下沒(méi)查到商品的情況
// 把商品的價(jià)格加到總錢(qián)數(shù)上, a += b 是 a = a + b 的縮寫(xiě)
sum += data.price;
}
你居然花了一半的時(shí)間在讀注釋上面,這是多么浪費(fèi)生命的事情,在代碼中每加一行注釋?zhuān)紩?huì)增加代碼的閱讀成本——即使閱讀者已經(jīng)了解了注釋所要傳達(dá)的精神;同時(shí)也會(huì)增加維護(hù)成本:修改這段代碼的人不得不連同注釋一起修改——而且你不能確定他到底會(huì)不會(huì)這么做。
所以只有當(dāng)非常必要的情況下,才應(yīng)該添加注釋?zhuān)覒?yīng)當(dāng)言簡(jiǎn)意賅。注釋不應(yīng)當(dāng)解釋一段代碼在做什么,因?yàn)檫@是每個(gè)合格的程序員都應(yīng)該知道的事情,而是應(yīng)該解釋這段代碼為什么要這樣做。
由此引出幾種明顯不應(yīng)該添加的注釋?zhuān)?/p>
本應(yīng)由版本控制系統(tǒng)記錄的信息、對(duì)代碼的評(píng)論,以及不是很重要的 TODO.
代碼并不是全部,一個(gè)但凡靠譜一點(diǎn)的項(xiàng)目,都應(yīng)當(dāng)有自己的版本控制系統(tǒng),除了記錄代碼差異之外,還應(yīng)該有工單和 Issue 的功能。
閱讀代碼的人通常不需要了解幾個(gè)程序員之間的恩怨,很多時(shí)候也不關(guān)心這段代碼的歷史,這些信息只會(huì)把代碼拖得越來(lái)越長(zhǎng)。
廢棄的代碼
被棄用的代碼應(yīng)該被刪掉,這些代碼會(huì)非常影響閱讀,而且它們一般又很長(zhǎng)。
在絕大多數(shù)情況下,被棄用的代碼不會(huì)重新派上用場(chǎng),即使出現(xiàn)了少數(shù)情況,你也可以從版本控制系統(tǒng)中找到它們。
對(duì)變量和函數(shù)名的解釋
這種情況下顯然你需要一個(gè)更恰當(dāng)?shù)拿?,如果這個(gè)標(biāo)識(shí)符有一個(gè)比較小的作用于,你可以使用一個(gè)比較長(zhǎng)的名字以便容納更多信息。
例如上文中的:
products 應(yīng)改為 products_id
sum 應(yīng)改為 total_amount
data 應(yīng)改為 product_record
對(duì)語(yǔ)法的解釋?zhuān)约帮@而易見(jiàn)的事情
例如上文中的「把商品的價(jià)格加到總錢(qián)數(shù)上, a += b 是 a = a + b 的縮寫(xiě)」,這顯然是任何一個(gè)人都知道的事情。
也許有人愿意通過(guò)寫(xiě)這樣的注釋來(lái)梳理思路:
復(fù)制代碼 代碼如下:
// 過(guò)濾參數(shù):
// 去掉 ID 里的空格
// 去掉非數(shù)字 ID
// 循環(huán)每一個(gè)商品:
// 去數(shù)據(jù)庫(kù)查記錄
// 把商品的價(jià)格加到總錢(qián)數(shù)上
但是當(dāng)代碼寫(xiě)完的時(shí)候記得刪掉。
對(duì)邏輯塊的概括
例如上文中的「過(guò)濾每個(gè)參數(shù)」和「計(jì)算每個(gè)商品的總錢(qián)數(shù)」,這情況下通常是你沒(méi)有對(duì)邏輯進(jìn)行抽象,具體表現(xiàn)就是像下面這樣:
復(fù)制代碼 代碼如下:
// 首先有 25 行代碼去做事情 A
// 然后有 5 行代碼去做事情 B
// 這里有 90 行代碼去做事情 C
// 最后有 45 行代碼去做事情 D
這導(dǎo)致你需要一些注釋來(lái)分割這四個(gè)部分。如果這四個(gè)部分都是一個(gè)函數(shù)調(diào)用的話,那么函數(shù)名本身就是對(duì)邏輯的一種解釋?zhuān)x者可以快速地找到函數(shù) B, 而不必在前 25 行中搜索做事情 B 的五行代碼。
綜上,我對(duì)這段代碼的改善意見(jiàn)如下:
復(fù)制代碼 代碼如下:
var filterProductID = function(raw_products_id) {
result = []
raw_products_id.forEach(function(product_id) {
if (product_id and product_id.trim())
products_id.push(product_id.trim().toFixed());
});
return result;
};
var getPriceOfProduct = function(id) {
var product_record = db.product.byID(products[i]);
if (product_record)
return product_record.price;
else
return 0;
};
var products_id = filterProductID(req.query['products'].split(','));
var tatol_amount = 0;
products_id.forEach(function(product_id) {
tatol_amount += getPriceOfProduct(product_id);
});
雖然我在以一段虛構(gòu)的,刻意編造的代碼來(lái)佐證我的觀點(diǎn),但我相信在實(shí)際的項(xiàng)目中,同樣可以通過(guò)改善代碼來(lái)減少注釋?zhuān)铱傮w上來(lái)講會(huì)節(jié)約更多的時(shí)間和精力。
您可能感興趣的文章:
相關(guān)文章
-
用戶權(quán)限管理設(shè)計(jì)[圖文說(shuō)明]
用戶管理權(quán)限設(shè)計(jì)一直是大家討論的熱點(diǎn),因?yàn)閹缀跎婕暗矫恳粋€(gè)開(kāi)發(fā)的業(yè)務(wù)系統(tǒng)。我找了很多很多的資料,大家的核心基本上都是一樣的:基于角色管理. 用戶,角色,模塊,權(quán)限的相互組合,就可以形成一個(gè)強(qiáng)大的權(quán)限管理系統(tǒng)。 2008-12-12
-
JetBrains(IEDA、CLion、Pycharm) 學(xué)生獲得免費(fèi)使用資格
JetBrains針對(duì)學(xué)生推出了免費(fèi)使用資格,但是很多同學(xué)卻不知道或者說(shuō)不知道怎樣獲得免費(fèi)資格,通過(guò)學(xué)生認(rèn)證來(lái)使用JetBrains的軟件才是最方便穩(wěn)定的,具體怎么獲取呢,感興趣的朋友跟隨小編一起看看吧 2020-08-08
-
微信支付 :curl出錯(cuò),錯(cuò)誤碼:60兩個(gè)問(wèn)題的解決
這篇文章主要介紹了微信支付 出錯(cuò)的解決辦法的相關(guān)資料,需要的朋友可以參考下 2016-09-09
-
IDEA中使用Git拉取代碼時(shí)報(bào) Git pull failed原因及解決方法
這篇文章主要介紹了IDEA中使用Git拉取代碼時(shí)報(bào) Git pull failed原因及解決方法,本文給大家介紹的非常詳細(xì)對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下 2020-08-08
最新評(píng)論
當(dāng)很多前輩教育后輩應(yīng)當(dāng)多寫(xiě)注釋的時(shí)候,當(dāng)網(wǎng)絡(luò)上充滿了有關(guān)程序員從不寫(xiě)注釋的段子的時(shí)候,這是一個(gè)非常有爭(zhēng)議的話題。作為一個(gè)標(biāo)題黨,容我先修正一下我的觀點(diǎn):我認(rèn)為如果代碼寫(xiě)得足夠好,那么大多數(shù)注釋是多余的,我們應(yīng)該通過(guò)寫(xiě)出更好的代碼來(lái)代替更多注釋。
注釋的確有其用途,但大部分情況下,程序員在濫用注釋。我是反對(duì)夾雜在代碼間的注釋的,我認(rèn)為注釋?xiě)?yīng)當(dāng)從代碼中獨(dú)立出來(lái)——通常被稱(chēng)為文檔。
請(qǐng)看下面一段代碼。
/* /static/market/checkout.js
2014.7.2 create by orzfly
2014.7.29 update by jysperm: fixbugs
TODO: 這段代碼中注釋太多了,需要移除一些 -- jysperm
*/
var raw_products = req.query['products'].split(',');
// 商品 ID 的數(shù)組
var products = []
// 過(guò)濾每個(gè)參數(shù)
for(var i = 0, i < raw_products.length, i++) {
if (!raw_products[i])
return;
// 前端傳來(lái)的數(shù)據(jù)中居然會(huì)有空格
if (!raw_products[i].trim())
return
/* 2014.7.22: 現(xiàn)在可以使用非數(shù)字 ID 了
// 略過(guò)非數(shù)字條目
if (isNan(raw_products[i].trim().toFixed()))
return;
*/
products.push(raw_products[i].trim().toFixed());
}
// 總錢(qián)數(shù)
var sum = 0;
// 計(jì)算每個(gè)商品的總錢(qián)數(shù)
for(var i = 0, i < products.length, i++) {
// 從數(shù)據(jù)庫(kù)中查商品信息
var data = db.product.byID(products[i]);
// TODO: 誰(shuí)來(lái)寫(xiě)一下沒(méi)查到商品的情況
// 把商品的價(jià)格加到總錢(qián)數(shù)上, a += b 是 a = a + b 的縮寫(xiě)
sum += data.price;
}
你居然花了一半的時(shí)間在讀注釋上面,這是多么浪費(fèi)生命的事情,在代碼中每加一行注釋?zhuān)紩?huì)增加代碼的閱讀成本——即使閱讀者已經(jīng)了解了注釋所要傳達(dá)的精神;同時(shí)也會(huì)增加維護(hù)成本:修改這段代碼的人不得不連同注釋一起修改——而且你不能確定他到底會(huì)不會(huì)這么做。
所以只有當(dāng)非常必要的情況下,才應(yīng)該添加注釋?zhuān)覒?yīng)當(dāng)言簡(jiǎn)意賅。注釋不應(yīng)當(dāng)解釋一段代碼在做什么,因?yàn)檫@是每個(gè)合格的程序員都應(yīng)該知道的事情,而是應(yīng)該解釋這段代碼為什么要這樣做。
由此引出幾種明顯不應(yīng)該添加的注釋?zhuān)?/p>
本應(yīng)由版本控制系統(tǒng)記錄的信息、對(duì)代碼的評(píng)論,以及不是很重要的 TODO.
代碼并不是全部,一個(gè)但凡靠譜一點(diǎn)的項(xiàng)目,都應(yīng)當(dāng)有自己的版本控制系統(tǒng),除了記錄代碼差異之外,還應(yīng)該有工單和 Issue 的功能。
閱讀代碼的人通常不需要了解幾個(gè)程序員之間的恩怨,很多時(shí)候也不關(guān)心這段代碼的歷史,這些信息只會(huì)把代碼拖得越來(lái)越長(zhǎng)。
廢棄的代碼
被棄用的代碼應(yīng)該被刪掉,這些代碼會(huì)非常影響閱讀,而且它們一般又很長(zhǎng)。
在絕大多數(shù)情況下,被棄用的代碼不會(huì)重新派上用場(chǎng),即使出現(xiàn)了少數(shù)情況,你也可以從版本控制系統(tǒng)中找到它們。
對(duì)變量和函數(shù)名的解釋
這種情況下顯然你需要一個(gè)更恰當(dāng)?shù)拿?,如果這個(gè)標(biāo)識(shí)符有一個(gè)比較小的作用于,你可以使用一個(gè)比較長(zhǎng)的名字以便容納更多信息。
例如上文中的:
products 應(yīng)改為 products_id
sum 應(yīng)改為 total_amount
data 應(yīng)改為 product_record
對(duì)語(yǔ)法的解釋?zhuān)约帮@而易見(jiàn)的事情
例如上文中的「把商品的價(jià)格加到總錢(qián)數(shù)上, a += b 是 a = a + b 的縮寫(xiě)」,這顯然是任何一個(gè)人都知道的事情。
也許有人愿意通過(guò)寫(xiě)這樣的注釋來(lái)梳理思路:
// 過(guò)濾參數(shù):
// 去掉 ID 里的空格
// 去掉非數(shù)字 ID
// 循環(huán)每一個(gè)商品:
// 去數(shù)據(jù)庫(kù)查記錄
// 把商品的價(jià)格加到總錢(qián)數(shù)上
但是當(dāng)代碼寫(xiě)完的時(shí)候記得刪掉。
對(duì)邏輯塊的概括
例如上文中的「過(guò)濾每個(gè)參數(shù)」和「計(jì)算每個(gè)商品的總錢(qián)數(shù)」,這情況下通常是你沒(méi)有對(duì)邏輯進(jìn)行抽象,具體表現(xiàn)就是像下面這樣:
// 首先有 25 行代碼去做事情 A
// 然后有 5 行代碼去做事情 B
// 這里有 90 行代碼去做事情 C
// 最后有 45 行代碼去做事情 D
這導(dǎo)致你需要一些注釋來(lái)分割這四個(gè)部分。如果這四個(gè)部分都是一個(gè)函數(shù)調(diào)用的話,那么函數(shù)名本身就是對(duì)邏輯的一種解釋?zhuān)x者可以快速地找到函數(shù) B, 而不必在前 25 行中搜索做事情 B 的五行代碼。
綜上,我對(duì)這段代碼的改善意見(jiàn)如下:
var filterProductID = function(raw_products_id) {
result = []
raw_products_id.forEach(function(product_id) {
if (product_id and product_id.trim())
products_id.push(product_id.trim().toFixed());
});
return result;
};
var getPriceOfProduct = function(id) {
var product_record = db.product.byID(products[i]);
if (product_record)
return product_record.price;
else
return 0;
};
var products_id = filterProductID(req.query['products'].split(','));
var tatol_amount = 0;
products_id.forEach(function(product_id) {
tatol_amount += getPriceOfProduct(product_id);
});
雖然我在以一段虛構(gòu)的,刻意編造的代碼來(lái)佐證我的觀點(diǎn),但我相信在實(shí)際的項(xiàng)目中,同樣可以通過(guò)改善代碼來(lái)減少注釋?zhuān)铱傮w上來(lái)講會(huì)節(jié)約更多的時(shí)間和精力。
相關(guān)文章
用戶權(quán)限管理設(shè)計(jì)[圖文說(shuō)明]
用戶管理權(quán)限設(shè)計(jì)一直是大家討論的熱點(diǎn),因?yàn)閹缀跎婕暗矫恳粋€(gè)開(kāi)發(fā)的業(yè)務(wù)系統(tǒng)。我找了很多很多的資料,大家的核心基本上都是一樣的:基于角色管理. 用戶,角色,模塊,權(quán)限的相互組合,就可以形成一個(gè)強(qiáng)大的權(quán)限管理系統(tǒng)。2008-12-12JetBrains(IEDA、CLion、Pycharm) 學(xué)生獲得免費(fèi)使用資格
JetBrains針對(duì)學(xué)生推出了免費(fèi)使用資格,但是很多同學(xué)卻不知道或者說(shuō)不知道怎樣獲得免費(fèi)資格,通過(guò)學(xué)生認(rèn)證來(lái)使用JetBrains的軟件才是最方便穩(wěn)定的,具體怎么獲取呢,感興趣的朋友跟隨小編一起看看吧2020-08-08微信支付 :curl出錯(cuò),錯(cuò)誤碼:60兩個(gè)問(wèn)題的解決
這篇文章主要介紹了微信支付 出錯(cuò)的解決辦法的相關(guān)資料,需要的朋友可以參考下2016-09-09IDEA中使用Git拉取代碼時(shí)報(bào) Git pull failed原因及解決方法
這篇文章主要介紹了IDEA中使用Git拉取代碼時(shí)報(bào) Git pull failed原因及解決方法,本文給大家介紹的非常詳細(xì)對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08