Bài viết gốc: https://medium.freecodecamp.org/code-comments-the-good-the-bad-and-the-ugly-be9cc65fbf83.

Dịch giả: Togahepi a.k.a Hà Hiệp.

Thiện, Ác, Tà : The Good, The Bad and The Ugly. Phim hay lắm, kinh điển luôn nhớ xem sau khi đọc bài này nha :))

Clint Eastwood - đẹp trai, giờ già rồi vẫn còn gân lắm
Clint Eastwood - đẹp trai, giờ già rồi vẫn còn gân lắm!

Chắc hẳn bạn đã từng nghe tới câu nói này:

"Good code is self-documenting." - Code tốt thì chẳng cần comment!

Trong suốt hơn 20 năm có lẻ viết code để kiếm cơm của tôi đây có lẽ là câu nói tôi nghe được nhiều nhất.

Nghe thật sáo rỗng, rập khuôn.

Giống như bao lời sáo rỗng và rập khuôn khác, nó luôn có một sự thật sâu kín bên trong. Nhưng sự thật đó bị đày đọa ở một nơi rất xa khiến cho những người phát ngôn ra câu nói đó chẳng hiểu ý nghĩa thực sự của nó là gì.

Vậy câu nói đó có đúng? Vâng, có ạ.

Vậy nghĩa là bạn không bao giờ phải comment trong code của mình? Không, đừng như vậy nhé.

Trong bài viết này chúng ta sẽ xem rằng thiện, ác và tà sẽ như thế nào khi comment trong code.

Đầu tiên, có 2 loại comment khác nhau trong code. Đó là "comment mang tính tài liệu" và "comment mang tính giải thích".

Comment mang tính tài liệu - Documentation Comments (viết tắt DC)

DC được sử dụng khi một ai đó muốn sử dụng code của bạn nhưng không muốn đọc toàn bộ chúng. Nếu bạn đang xây dựng 1 thư viện hay 1 framework cho các developer khác sử dụng, bạn sẽ cần một số dạng tài liệu của API.

Tài liệu API càng xa rời source code thì sẽ càng dễ lỗi thời và thiếu chính xác theo thời gian. Có một cách hay đó là gắn luôn tài liệu thẳng vô code sau đó dùng tool để trích xuất nó.

Đây là một ví dụ về DC trong một thư viện JavaScript tên Lodash.

 /**
     * Creates an object composed of keys generated from the results of running
     * each element of `collection` thru `iteratee`. The corresponding value of
     * each key is the number of times the key was returned by `iteratee`. The
     * iteratee is invoked with one argument: (value).
     *
     * @static
     * @memberOf _
     * @since 0.5.0
     * @category Collection
     * @param {Array|Object} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
     * @returns {Object} Returns the composed aggregate object.
     * @example
     *
     * _.countBy([6.1, 4.2, 6.3], Math.floor);
     * // => { '4': 1, '6': 2 }
     *
     * // The `_.property` iteratee shorthand.
     * _.countBy(['one', 'two', 'three'], 'length');
     * // => { '3': 2, '5': 1 }
     */
    var countBy = createAggregator(function(result, value, key) {
      if (hasOwnProperty.call(result, key)) {
        ++result[key];
      } else {
        baseAssignValue(result, key, 1);
      }
    });
view rawdoc_comment_from_lodash.js hosted with ❤ by 

Nếu bạn so sánh những comment này với tài liệu online của họ, bạn sẽ thấy chúng giống hệt nhau.

Nếu bạn viết DC bạn nên chú ý rằng chúng theo đúng một chuẩn cố định và phân tách rõ ràng với bất kì comment giải thích mà bạn muốn thêm vào. Một số chuẩn và công cụ hỗ trợ phổ biến như JSDoc cho JavaScript, DocFx cho dotNet và JavaDoc cho Java.

Mặt trái của dạng comment này đó là chúng có thể làm code của bạn trông "rối rắm" và khó đọc cho những ai thường xuyên phải bảo trì nó. Tin tốt đó là hầu hết những trình biên soạn code đều hỗ trợ "gói gọn code" cho phép chúng ta có thể thu hẹp đoạn comment lại và tập trung hơn vào những dòng code.

code folding
Thu gọn comment trong Visual Studio Code.

Comment giải thích - Clarification comments (viết tắt CC)

CC được tạo ra để bất kì ai (bao gồm chính bạn trong tương lai) người mà sẽ bảo trì, refactor hoặc mở rộng code đó.

Thường thì, CC nói lên rằng code bạn đang thúi quá đó. :)) Nó chỉ ra code bạn đang quá phức tạp. Bạn nên cố gắng hết sức để loại bỏ CC và đơn giản hóa code bởi vì "code tốt là code tự comment".

Đây là một ví dụ xấu - nhưng vui vẻ ra trò - về comment giải thích.

/* 
 * Replaces with spaces 
 * the braces in cases 
 * where braces in places 
 * cause stasis.
**/ 
$str = str_replace(array("\{","\}")," ",$str);

Thay vì trang trí một câu lệnh có vẻ hơi khó hiểu với một bài thơ đầy trí tuệ với vần điệu hay ho - thì tác giả nên dành nhiều thời gian để đặt tên function để nó có thể dễ đọc và hiểu hơn. Có lẽ nên đặt tên function này là, removeCurlyBraces (loaiBoNgoacNhon) được gọi từ một function khác tên sanitizeInput (thuGonDauVao)?

Đừng hiểu lầm tôi, nhưng mà cũng sẽ có lúc - đặc biệt khi bạn cặm cụi miệt mài trong công việc bộn bề - thêm vào một chút hài hước sẽ vô cùng tốt trong tâm hồn của bạn đó. Nhưng khi bạn thêm một comment vui vẻ để trang trí một đoạn "code thúi", nó thực sự sẽ khiến mọi người chẳng muốn refactor và sửa lỗi code.

Bạn có thực sự muốn trở thành kẻ tội đồ đánh cắp niềm vui của những coder tương lai khi đọc những giai điệu thông thái đó? Hầu hết coder sẽ cười thầm và bỏ qua những đoạn code thúi.

Cũng có lúc bạn sẽ gặp phải một comment vô cùng thừa thãi. Nếu code bạn đơn giản và dễ hiểu, không cần thiết phải thêm comment làm gì cả.

Giống như vầy, đừng như vầy:

/*
set the value of the age integer to 32
*/
int age = 32;

Nhưng vẫn có lúc mặc cho code bạn ra sao, một đoạn comment giải thích vẫn vô cùng cần thiết.

Thường là khi bạn cần thêm một một vài tình huống của những giải pháp không tự nhiên.

Đây là một ví dụ tốt từ Lodash:

function addSetEntry(set, value) {   
  /* 
   Don't return `set.add` because it's not chainable in IE 11.
  */  
  set.add(value);    
  return set;  
}

Rồi sẽ có lúc - qua bao gian khổ suy tư cũng như thử nghiệm - thì hóa ra những giải pháp trông vô cùng ngây thơ, gà mờ lại là tốt nhất. Và những lúc như thế thì điều không thể tránh khỏi đó là một số coder khác sẽ tưởng rằng họ thông minh hơn bạn nhiều và sẽ lại bày trò với những dòng code, rồi cuối cùng chỉ để khám phá ra rằng cách của bạn là cách tốt nhất.

Đôi khi coder khác đó lại chính là bản thân bạn trong tương lai đó.

Trong những trường hợp đó, điều tốt nhất để tiết kiệm thời gian và nỗi xấu hổ cho mọi người đó là nhớ để lại một comment.

Lời comment chế nhạo sau đây thể hiện rõ ràng cái viễn cảnh đó 1 cách hoàn hảo:

/**
Hỡi người anh em iu dấu:
 
Một khi bạn đã nản lòng khi "tối ưu" những đoạn code này,
và nhận ra rằng đã phạm 1 sai lầm kinh khủng,
xin hãy nâng số giờ đếm sau đây lên như một cảnh báo
cho gã tiếp theo nhé:
 
số_giờ_đã_phí_phạm = 42
**/

Và lại nữa, những dòng trên chỉ mang tính vui vẻ hơn là giúp ích. Nhưng bạn cũng NÊN để lại một comment cảnh báo cho người khác đừng cố theo đuổi giải pháp tốt hơn, nếu bạn đã cố gắng và phải từ bỏ nó. Và khi bạn làm điều đó, hãy để lại giải pháp mà bạn đã thử và vì sao bạn chọn nó.

Đây là một ví dụ đơn giản trong JavaScript:

/* 
don't use the global isFinite() because it returns true for null values
*/
Number.isFinite(value)

The Ugly - Kẻ xấu xa tà ác

Rồi, chúng ta đã chiêm ngưỡng người tốt, người xấu, vậy thì kẻ tà ác thì sao?

Thật không may, rồi cũng có lúc trong bất cứ công việc nào khi mà bạn cảm thấy chán nản kinh và nhất là khi bạn code để kiếm sống, nhiều lúc bạn sẽ không kiềm chế được mà trút những bực dọc đó vào những comment.

Làm việc đủ lâu với những code base, bạn sẽ được thấy đủ thể loại comment từ những lời lẽ cay độc, mỉa mai cho đến u sầu u uất và có khi đầy sự sôi nổi.

Những dòng này nghe có vẻ vô hại nè...

/*
Code này thúi lắm, bạn biết và tôi cũng biết.
Hãy cứ thoải mái gọi tôi là thằng ngốc đi nhoa!
*/

...cho đến sự cay độc dưới đây

/* 
Class được dùng bởi Richard ngu vãi!
*/

Những thứ này nghe có vẻ vui vẻ hoặc sẽ làm giảm bớt những giây phút mệt nhọc, nhưng khi mà cần một sản phẩm chuyên nghiệp thì những coder viết những dòng này thì thật kém sang và chua ngoa!

Đừng như vậy nha.