“Đừng comment trên Code xấu – Hãy viết lại nó.”
Không gì hữu ích hơn bằng một comment được đặt đúng chỗ. Nhưng cũng sẽ trở nên tồi tệ, gây nhiễu loạn thông tin khi đặt sai hay là cung cấp thông tin không đúng.
Việc dùng đúng những comment là một cách để bù đắp cho sự thất bại của chúng ta trong việc thể hiện ý nghĩa của những dòng code. Chính xác là vậy – comment luôn luôn là sự thất bại.
Vậy nên, khi bạn cần viết comment, bạn hãy suy nghĩ kỹ xem liệu có cách nào đó để biến các dòng code thành chính xác những gì bạn muốn thể hiện hay không.
Điều tin tưởng tuyệt đối nhất là: Code. Chỉ có code mới nói cho bạn biết thật sự là nó làm gì. Nó là nguồn thông tin chính xác duy nhất. Do đó, mặc dù comment đôi khi là cần thiết, nhưng chúng tôi sẽ cố gắng để giảm thiểu nó.
Đừng dùng comments để trang trí cho mã xấu (Comments Do Not Make Up for Bad Code)
Một trong những động lực to lớn để viết comment là do code tồi, code tối nghĩa.
Khi chúng ta viết một module và chúng ta biết rằng nó lộn xộn và vô tổ chức. Chúng ta biết nó bữa bộn Vậy nên chúng ta tự nhủ rằng: “Ồ, tốt hơn nên viết comment ở đây!”. Không! Tốt hơn bạn nên viết lại code!
Code rõ ý nghĩa và rõ ràng với ít comment sẽ tuyệt vời hơn so với code tối nghĩa, phức tạp với nhiều comment. Thay vì dành thời gian để viết bình luận cho mớ lộn xộn, bạn nên dọn dẹp nó.
Giải thích ý nghĩa ngay trong code(Explain Yourself in Code)
Trong nhiều trường hợp, việc thay thế code nghèo nàn bằng cách tạo ra những hàm mới đã nói lên đủ những lời comment mà bạn muốn viết dành riêng cho đoạn code đó.
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) &&
(employee.age > 65))
Hay cái này?
if (employee.isEligibleForFullBenefits())
Good Comments
Một số comment là cần thiết hoặc có ích. Chúng ta sẽ xem một số trường hợp được cho là xứng đáng để bạn bỏ công ra viết.
-
Bình luận pháp lý (Legal Comments)
Điều này tùy thuộc vào tiêu chuẩn viết code của dự án bạn đang làm. Ví dụ: Bản quyền và quyền tác giả là điều cần thiết và hợp lý để đưa vào comment lúc bắt đầu của mỗi tập tin mã nguồn.
/* Copyright (C) 2003,2004,2005 by Object Mentor, Inc.
* All rights reserved.
* Released under the terms of the GNU General Public License version
* 2 or later.
*/
-
Bình luận cung cấp thông tin (Informative Comments)
Cung cấp thông tin với vài dòng comment đôi khi khá là hữu dụng.
// Returns an instance of the Responder being tested.
protected abstract Responder responderInstance();
Một comment như vậy đôi khi khá là hữu ích, nhưng tốt hơn hết là nên truyền tải thông tin thông qua tên của function nếu có thể. (responderBeingTested.)
// format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Pattern.compile(
“\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*”);
Trong trường hợp này comment cho chúng ta biết định dạng về thời gian trong hàm SimpleDateFormat.format với một chuỗi xác định. Tuy nhiên, nó vẫn có thể rõ ràng hơn nếu mã này được chuyển sang một lớp đặc biệt với mục đích chuyển đổi định dạng thời gian. Sau đó, những comment có thể sẽ không cần thiết nữa.
-
Giải thích về mục đích (Explanation of Intent)
Đôi khi comment không chỉ cung cấp thông tin về những dòng code mà còn cung cấp ý định đằng sau nó.
public int compareTo(Object o)
{
if(o instanceof WikiPagePath)
{
WikiPagePath p = (WikiPagePath) o;
String compressedName = StringUtil.join(names, “”);
String compressedArgumentName = StringUtil.join(p.names, “”);
return compressedName.compareTo(compressedArgumentName);
}
return 1; // we are greater because we are the right type.
}
-
Làm dễ hiểu (Clarification)
Đôi khi bạn cần dùng comment để diễn giải ý nghĩa của các đối số khó hiểu hoặc giá trị trả về, để biến chúng thành thứ gì đó có thể hiểu được.
Nhưng chỉ khi một phần thư viện chuẩn hoặc trong code mà bạn không thể thay đổi được, một bình luận có thể sẽ hữu ích.
{
WikiPagePath a = PathParser.parse(“PageA”);
WikiPagePath ab = PathParser.parse(“PageA.PageB”);
WikiPagePath b = PathParser.parse(“PageB”);
WikiPagePath aa = PathParser.parse(“PageA.PageA”);
WikiPagePath bb = PathParser.parse(“PageB.PageB”);
WikiPagePath ba = PathParser.parse(“PageB.PageA”);
assertTrue(a.compareTo(a) == 0); // a == a
assertTrue(a.compareTo(b) != 0); // a != b
assertTrue(ab.compareTo(ab) == 0); // ab == ab
assertTrue(a.compareTo(b) == -1); // a < b
assertTrue(aa.compareTo(ab) == -1); // aa < ab
assertTrue(ba.compareTo(bb) == -1); // ba < bb
assertTrue(b.compareTo(a) == 1); // b > a
assertTrue(ab.compareTo(aa) == 1); // ab > aa
assertTrue(bb.compareTo(ba) == 1); // bb > ba
}
Dĩ nhiên, khả năng các comment dạng này cung cấp thông tin không chính xác là khá cao. Làm dễ hiểu (Clarification) là cần thiết và nó cũng đầy rủi ro. Vì vậy, trước khi viết bình luận như vậy hãy quan tâm xem có cách nào tốt hơn không, để có một lựa chọn đúng đắn nhất.
-
Cảnh báo về các hậu quả (Warning of Consequences)
Đôi khi nó rất hữu ích để cảnh báo các lập trình viên khác về hậu quả xảy ra. Ví dụ, giải thích lý do tại sao một test case cụ thể bị tắt đi:
// Don’t run unless you
// have some time to kill.
public void _testWithReallyBigFile()
{
writeLinesToFile(10000000);
response.setBody(testFile);
response.readyToSend(this);
String responseString = output.toString();
assertSubString(“Content-Length: 1000000000”, responseString);
assertTrue(bytesSent > 1000000000);
}
Có thể còn nhiều cách tốt hơn để giải quyết vấn đề này. Tôi đồng ý. Nhưng bình luận được đưa ra ở đây là hoàn toàn hợp lý. Nó ngăn chặn một số lập trình viên khác.
-
TODO Comments
TODO là những công việc mà lập trình viên nghĩ là cần nên làm, nhưng vì lý do nào đó mà họ không thể thực hiện nó ngay lúc này. Nó có thể là một lời nhắc nhở để xóa một tính năng không cần thiết, một lời bào chữa cho ai đó khi nhìn vào vấn đề.
Nó có thể là một yêu cầu dành cho ai đó để nghĩ ra một cái tên hay hơn, hay nhắc nhở về một sự thay đổi nào đó cho sự kiện đã được lên kế hoạch từ trước. Nhưng dù TODO có là gì đi nữa, nó chắc chắn không phải là lý do để bạn quăng đống code ẩu, code bừa vào dự án.
-
Amplification (Phóng đại)
Comment có thể được dùng để khuếch đại tầm quan trọng của một cái gì đó có vẻ không quan trọng:
String listItemContent = match.group(3).trim();
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognized
// as another list.
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()));
-
Javadocs in Public APIs
Không có gì hữu ích và tuyệt vời bằng public API được mô tả tốt. Các javadoc của thư viện chuẩn của Java là một trường hợp điển hình. Sẽ rất khó để viết các chương trình Java mà thiếu chúng.
Bad Comments
Đa số các comment rơi vào thể loại này. Chúng thường được sử dụng như cái cớ cho việc viết code rởm hoặc biện minh cho các cách giải quyết đầy thiếu sót.
-
Độc thoại
Quăng vào một comment chỉ vì bạn thấy thích.
- Các comment thừa thải.
Những comment này, có lẽ, còn làm người đọc mất thời gian hơn so với việc đọc code của hàm.
- Các comment sai sự thật.
….Update …
Bài viết cùng chủ đề:
- Clean code tiếng việt Chap 1
- Clean code tiếng việt chap 2
- Clean code tiếng việt chap 6 – ĐỐI TƯỢNG VÀ CẤU TRÚC DỮ LIỆU