Comments

Brian W. Kernighan and P. J. Plaugher đã nói:

Don't comment bad code -- rewrite it.

Comments là cần thiết. Tuy nhiên, không phải lúc nào ta cũng cần tới nó. Khi gặp những pharse/line code mess, nhiều lập trình viên thay bằng việc refactoring code hoặc rewrite code cho dễ hiểu thì lại thêm comments vào code. Refactoring code không đơn giản chỉ là cho code dễ đọc, dễ hiểu hơn. Nó còn giúp cho việc bảo trì và phát triển thêm tính năng mới dễ dàng hơn. Việc thêm comments thì chỉ là để làm rõ nghĩa cho pharse/line code đó. Rõ ràng, refactoring code nó có ý nghĩa nhiều hơn việc comment vào code. Tất nhiên, có những logic code phức tạp,... thì comments là điều cần thiết. Do đó, nếu code hiện tại quá mess, thì việc comment nó sẽ chẳng có ý nghĩa gì ở đây. Thay vì đó hãy refactoring code hay rewrite code đi!!!

Comments Do Not Make Up for Bad Code

Code clear và expressive (sạch sẽ và có ý nghĩa) cùng với ít comment sẽ tốt hơn rất nhiều việc Code cluttered and complex (lộn xộn và phức tạp) với nhiều comment. Thay vì dành thời gian cho việc comment vào mess code, bạn hãy clean code đi.

Explain Yourself in Code

Một trong những lý do nhiều nhất khi lập trình viên sử dụng comments là làm giải thích đoạn code của mình:

// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) {...}

Nếu bỏ comment, thay vào đó, đặt tên biến và tên function rõ nghĩa hơn như thế này:

if (employee.isEligibleForFullBenefits())

Bạn có thể thấy ngay, mặc dụ không cần comment, đoạn code trên vẫn hoàn toàn dễ hiểu!!!. Đó là lý do, bạn hãy cố gắng biến chính những đoạn code mình viết giải thích cho chính nó.

Good Comments

Như đã nói ở phần giới thiệu. Một số comment là cần thiết hoặc có lợi ích.

Legal Comments

Đôi khi, các chuẩn của một công ty buộc họ phải viết comments vì lý do pháp lý. Ví dụ như Copyright là cần thiết và hợp lý nếu chúng ta đưa vào comment ở đầu mỗi source file.

Những comment như thế này không phải là contract hay license. Nếu có thể, hãy tham khảo license chuẩn hoặc tài liệu bên ngoài khác thay vì đưa tất cả các điều khoản vào comment.

Ví dụ điển hình:

/* Copyright (C) YoYoDyne Systems, Inc - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 * Written by Elmer Fudd <[email protected]>, September 1943
 */

Informative Comments

Đôi khi, việc comment là hữu ích khi cung cấp một thông tin cơ bản. Ví dụ:

...
    // Returns an instance of the Responder being tested.
    return responderInstance();

Tất nhiên, comment này là hữu ích. Nhưng sẽ tốt hơn nếu sử dụng một tên function có ý nghĩa hơn. Cụ thể:

...
    return responderBeingTested();

Dưới đây là một ví dụ khác:

# format matched kk:mm:ss EEE, MMM dd, yyyy
time_matcher = re.match("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*", str_input).group(0)

OK. Ví dụ này, comment giải thích cho việc sử dụng regex để match với date time đã được format. Tuy nhiên, cũng sẽ tốt hơn khi move nó qua một function:

def format_date(str_input):
    return re.match("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*", str_input).group(0)

Explanation of Intent

Đôi khi, dòng dòng comment sẽ vượt ra ngoài việc cung cấp thông tin hữu ích. Nó còn cung cấp ý định đằng sau một quyết định.

...
# Today, 2048MB/s is max speed hard drive can write
if (speed_write > 2048):
    print("HDD is supper hard drive")

Clarification

  • Dịch nghĩa các argument ẩn.
  • Trả lại giá trị thành cái gì đó có thể đọc được Nói chung là tìm cách làm rõ argument và return value theo cách riêng của mình. Tuy nhiên, khi đó là một phần của library chuẩn, hoặc bạn chỉ có quyền đọc nó thì lúc này comment là hữu ích.

Ví dụ:

def test_compare_to():
    a = PathParser.parse("PageA")
    ab = PathParser.parse("PageA.PageB")
    b = PathParser.parse("PageB")
    aa = PathParser.parse("PageA.PageA")
    bb = PathParser.parse("PageB.PageB")
    ba = PathParser.parse("PageB.PageA")

    assert a.compare_to(a) == 0)  # a == a
    assert a.compare_to(b) != 0)  # a != a
    assert ab.compare_to(ab) == 0)  # ab == ab
    assert a.compare_to(b) == -1)  # a < b
    assert aa.compare_to(ab) == -1)  # aa < ab
    assert ba.compare_to(bb) == -1)  # ba < bb
    assert ab.compare_to(aa) == 1)  # ab > aa
    assert bb.compare_to(ba) == 1)  # b > ba

Có thể thấy như ví dụ trên, bạn có thể thấy khó khăn như thế nào để thấy rằng chúng là chính xác. Điều này giải thích cho việc, vì sao comment để làm rõ là cần thiết. Tuy nhiên, chúng cũng có rủi ro. Do đó, trước khi comment vào code, hãy thử xem còn các nào khác để làm rõ nghĩa hơn việc comment không?

Warning of Consequences

Comments đôi khi cũng giúp việc cảnh báo coder khi chạy dòng code đó sẽ ảnh hưởng như thế nào.

Ví dụ:

// 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);
}

TODO Comments

TODO là những việc mà coder nghĩ là nên làm nhưng vì một lý do nào đó không làm gì lúc này. Nó cũng có thể là một lời nhắc nhở rằng phải xóa tính năng ko được sử dụng nữa hoặc lời bào chữa cho người xem một vấn đề nào đó. Nó cũng có thể là một yêu cầu người khác nghĩ tới một cái tên tốt hơn hoặc một lời nhắc nhở để thực hiện một thay đổi phụ thuộc vào một sự kiến đã lên kế hoạch.

# TODO-MdM these are not needed
# We expect this to go away when we do the checkout model

def make_version():
    return

Ngày nay, một vài IDE cho phép thông báo cho bạn về việc có TODO trong code hằng ngày và bạn hãy cố gắng loại bỏ những cái bạn có thể.

Amplification

Một comment có thể được sử dụng để khuếch đại sự quan trọng của một đối tượng hoặc một đoạn code.

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()));

Bad Comments

Mumbling

Nếu bạn quyết định viết một comment. Bạn phải cố gắng để đảm bảo, đó là comment tốt nhất của bạn. Đó sẽ là những comments:

  • Comments không gây hiểu lầm: comments cần rõ nghĩa, không mập mờ, tránh gây hiểu lầm cho người đọc code
  • Comments không gây nhiễu: comments nên tập trung vào chủ đích comment không lan man
  • Comments không chứa quá nhiều thông tin: comment chỉ nên nói 1 chủ đích. .... Dưới đây là một ví dụ về việc comment cẩu thả:
public void loadProperties()
{
    try
    {
        String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE;
        FileInputStream propertiesStream = new FileInputStream(propertiesPath);
        loadedProperties.load(propertiesStream);
    }
    catch(IOException e)
    {
        // No properties files means all defaults are loaded
    }
}

Commented-Out Code

Cần loại bỏ những đoạn comments như thế này trong code. Tiêu chí luôn là, những gì không cần thiết thì xóa đi ngay và luôn.

def test_response(res):
    data = json.loads(res)
    if data["abc"] is True:h
        ...
    """
    else
        ...
    """

Dưới đây là một số điều mình đã đúc kết được khi tìm hiểu về comments trong code. Và đó là ý kiến chủ quan. Rất mong ý kiến đóng góp của mọi người.