當不少前輩教育後輩應當多寫註釋的時候,當網絡上充滿了有關程序員從不寫註釋的段子的時候,這是一個很是有爭議的話題。做爲一個標題黨,容我先修正一下個人觀點:我認爲若是代碼寫得足夠好,那麼大多數註釋是多餘的,咱們應該經過寫出更好的代碼來代替更多註釋。前端
註釋的確有其用途,但大部分狀況下,程序員在濫用註釋。我是反對夾雜在代碼間的註釋的,我認爲註釋應當從代碼中獨立出來——一般被稱爲文檔。程序員
請看下面一段代碼。數據庫
/* /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 的數組 var products = [] // 過濾每一個參數 for(var i = 0, i < raw_products.length, i++) { if (!raw_products[i]) return; // 前端傳來的數據中竟然會有空格 if (!raw_products[i].trim()) return /* 2014.7.22: 如今可使用非數字 ID 了 // 略過非數字條目 if (isNan(raw_products[i].trim().toFixed())) return; */ products.push(raw_products[i].trim().toFixed()); } // 總錢數 var sum = 0; // 計算每一個商品的總錢數 for(var i = 0, i < products.length, i++) { // 從數據庫中查商品信息 var data = db.product.byID(products[i]); // TODO: 誰來寫一下沒查到商品的狀況 // 把商品的價格加到總錢數上, a += b 是 a = a + b 的縮寫 sum += data.price; }
你竟然花了一半的時間在讀註釋上面,這是多麼浪費生命的事情,在代碼中每加一行註釋,都會增長代碼的閱讀成本——即便閱讀者已經瞭解了註釋所要傳達的精神;同時也會增長維護成本:修改這段代碼的人不得不連同註釋一塊兒修改——並且你不能肯定他到底會不會這麼作。數組
因此只有當很是必要的狀況下,才應該添加註釋,並且應當言簡意賅。註釋不該當解釋一段代碼在作什麼,由於這是每一個合格的程序員都應該知道的事情,而是應該解釋這段代碼爲何要這樣作。網絡
由此引出幾種明顯不該該添加的註釋:函數
本應由版本控制系統記錄的信息、對代碼的評論,以及不是很重要的 TODO.版本控制
代碼並非所有,一個但凡靠譜一點的項目,都應當有本身的版本控制系統,除了記錄代碼差別以外,還應該有工單和 Issue 的功能。
閱讀代碼的人一般不須要了解幾個程序員之間的恩怨,不少時候也不關心這段代碼的歷史,這些信息只會把代碼拖得愈來愈長。code
廢棄的代碼文檔
被棄用的代碼應該被刪掉,這些代碼會很是影響閱讀,並且它們通常又很長。
在絕大多數狀況下,被棄用的代碼不會從新派上用場,即便出現了少數狀況,你也能夠從版本控制系統中找到它們。get
對變量和函數名的解釋
這種狀況下顯然你須要一個更恰當的名字,若是這個標識符有一個比較小的做用於,你可使用一個比較長的名字以便容納更多信息。
例如上文中的:
對語法的解釋,以及顯而易見的事情
例如上文中的「把商品的價格加到總錢數上, a += b 是 a = a + b 的縮寫」,這顯然是任何一我的都知道的事情。
也許有人願意經過寫這樣的註釋來梳理思路:
// 過濾參數: // 去掉 ID 裏的空格 // 去掉非數字 ID // 循環每個商品: // 去數據庫查記錄 // 把商品的價格加到總錢數上
可是當代碼寫完的時候記得刪掉。
對邏輯塊的歸納
例如上文中的「過濾每一個參數」和「計算每一個商品的總錢數」,這狀況下一般是你沒有對邏輯進行抽象,具體表現就是像下面這樣:
// 首先有 25 行代碼去作事情 A // 而後有 5 行代碼去作事情 B // 這裏有 90 行代碼去作事情 C // 最後有 45 行代碼去作事情 D
這致使你須要一些註釋來分割這四個部分。若是這四個部分都是一個函數調用的話,那麼函數名自己就是對邏輯的一種解釋,讀者能夠快速地找到函數 B, 而沒必要在前 25 行中搜索作事情 B 的五行代碼。
綜上,我對這段代碼的改善意見以下:
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); });
雖然我在以一段虛構的,刻意編造的代碼來佐證個人觀點,但我相信在實際的項目中,一樣能夠經過改善代碼來減小注釋,並且整體上來說會節約更多的時間和精力。