+4

Clean code #6: Viết comment (P1)

1. Tại sao cần viết comment clean:

Comment thực sự có vị trí của nó. Nhưng vấn đề là việc quá phụ thuộc vào Comment là Code Smell. Comment chỉ nên được chọn là giải pháp sau khi đã cân nhắc các phương án thay thế. Cũng giống như bất kỳ cấu trúc dữ liệu nào khác, phải có lý do rõ ràng để giải thích cho sự tồn tại của chúng. Comments có thể là Signal to Noise.

Đôi khi, các comment không được cập nhật và chúng có thể được sử dụng để giải thích code khó hiểu, mà thực ra chúng có thể được cấu trúc lại theo cách gọn gàng hơn. Nhiều lập trình viên cho rằng code của họ đủ sạch đến mức không cần phải có comment để chú thích, nhưng như chúng ta đã thấy, việc truyền đạt rõ ràng ý định không phải là điều dễ dàng.

=> Có lẽ bạn đang tìm kiếm câu trả lời chắc chắn cho câu hỏi cốt lõi: "Comment có tuyệt vời không, hay chỉ là Code Smell?"

2. Một sự cần thiết và là một chỗ dựa:

Comment vừa là nhu cầu cần thiết, vừa là chỗ dựa. Hãy cùng xem xét một số quy tắc giúp định hướng cuộc trò chuyện của chúng ta:

a. Hãy ưu tiên code biểu cảm hơn là comment

Comment rất hữu ích, nhưng khi code có thể thực hiện cùng một công việc với độ rõ ràng tương đương, chúng ta nên chọn làm rõ ý định của mình trong code thay vì comment. Vì code có nhiều khả năng được các lập trình viên bảo trì cập nhật. Và là tài liệu tham khảo xác định cho những gì code đang thực hiện.

b. Sử dụng comment khi và chỉ khi cảm thấy chỉ code là không đủ ý nghĩa

Chúng ta nên sử dụng comment khi chỉ riêng code không đủ để cung cấp tài liệu cần thiết. Sau đây là danh sách các comment mà chúng ta nên tránh:

Header Header
Redundant Divider
Intent Brace Tracker
Apology Bloated Header
Warning Defect Log
Zombie Code

Chúng ta hãy cùng đi sâu vào từng phần trong bảng trên.

3. Redundant Comments:

Redundant Comments (Chú thích dư thừa) là những gì code nói ngay bên cạnh. Vì vậy, thực sự không có giá trị gia tăng nào ở đây. Hãy xem một vài ví dụ:

🔴 Dirty

int i = 1; // set i = 1

var passenger = new Passenger(); // Instantiate a new passenger

/// <summary>
/// Default Contructor
/// </summary>
class Passenger() {
  //
}

/// <summary>
/// Calculates Total Charges
/// </summary>
class CalculatesTotalCharges() {
  // Total charges calculated here
}

Phân tích ví dụ trên:

Dòng đầu tiên tôi đặt i thành 1. Điều này hoàn toàn rõ ràng trong đoạn code bên trái. Dòng thứ 2 tôi đang tạo một Passenger mới. Hoặc dòng thứ 3 tôi đang đánh dấu Default Constructor của mình, điều này là rõ ràng nếu tên củamethod khớp với tên của Class chẳng hạn. Cuối cùng, tôi đang tính tổng chi phí. Ở đây tôi đã nhắc lại tên chính xác của method của tôi trong comment (CalculatesTotalCharges).

Vấn đề với Redundant Comment là chúng phá vỡ Nguyên tắc DRY Bạn đang lặp lại chính mình. Bây giờ bạn đã tạo ra hai điểm khác nhau mà bạn phải duy trì và bạn thực sự không thêm giá trị nào. Điều này cũng làm giảm tỷ lệ signal to noise ratio. Đây là phần văn bản bổ sung mà người đọc thường đọc, nhưng họ không nhận được giá trị gì từ phần này vì không có nội dung mới nào ở đây.

❌ Vì vậy, bạn thường sẽ thấy những điều này khi mọi người yêu cầu comment về từng method và đặc biệt là ở đây, ví dụ như CalculateTotalCharges, không thực sự cần thiết phải thêm comment vào từng method nếu method của bạn được đặt tên tốt và trong trường hợp này, nó được đặt tên tốt nên không cần bổ sung comment để giải thích, nên bạn cũng có thể xóa nó đi và giải phóng một vài dòng trên màn hình. Tóm lại, đây là hai quy tắc để tránh Redundant Comment

  • Hãy giả sử người đọc của bạn có thể đọc được code bằng ngôn ngữ mà bạn đã viết.
  • DRY đừng lặp lại chính mình, bản thân code đã truyền tải mọi thông tin bạn cần cho những ví dụ đơn giản này. Nên bạn không cần phải comment nữa.

4. Intent Comments:

🔴 Dirty

// Assure user's account is deactivated
if(user.Status == 3)

Trong ví dụ này, lập trình viên đang sử dụng comment để làm rõ ý nghĩa của con số 3 kỳ diệu. Điều này dễ dàng được tái cấu trúc thông qua một hằng số được đặt tên tốt hoặc trong trường hợp này là một enum. Hãy xem ví dụ Clean, bây giờ, code đã truyền đạt rõ ràng ý định và không cần bạn phải comment.

🟢 Clean

if(user.Status == Status.InActive) {
  //
}

Có một số cách để tránh việc này:

  • Tạo một Intent Comment bao gồm việc cải thiện tên function/method
  • Khai báo một biến trung gian
  • Tạo một hằng số (const) hoặc một enum như chúng ta đã thấy ở ví dụ Clean trên
  • Cuối cùng, tái cấu trúc một điều kiện (conditional) thành một function/method có tên rõ ràng

5. Apology Comments:

Các comment xin lỗi. Đây là những comment khiến các lập trình viên làm nhiệm vụ bảo trì muốn khóc. Cuối cùng bạn đã điều hướng đến nơi lỗi được báo cáo và chỉ tìm thấy một comment như thế này.

🔴 Dirty

// Sorry, this is a crashed. It is a lot so I'm just swallowing the exception.

Những comment như thế này là dấu hiệu cho thấy lập trình viên ban đầu không thèm hoàn thành công việc. Đây là hành vi sai trái vì nó để lại mớ hỗn độn khiến người khác phải dọn dẹp sau đó. Và đây là một ví dụ khác

🔴 Dirty

// I was too tired to refactor is pile.
// of Spaghetti code when I was done...

Lập trình viên này đã quá kiệt sức sau khi chỉ mới làm cho nó hoạt động được, đến mức anh ấy để lại một mớ hỗn độn mà không ai khác có thể dễ dàng hiểu được.

✅ Hãy nhớ rằng không ai thích xin lỗi, vậy tại sao không tránh nó. Thay vào đó, hãy khắc phục sự cố trước khi bạn commit hoặc merge code của mình. Hoặc nếu vì lý do nào đó mà không thể thực hiện được thì hãy thêm comment đánh dấu TODO nếu cần.

6. Warning Comments:

Warning Comments có liên quan chặt chẽ đến Apology Comments mà chúng ta vừa thảo luận. Nhưng, có thể nói chúng thậm chí còn tệ hơn. Vì họ cũng cảnh báo rằng sẽ có lousy code, nhưng với Warning Comments, lập trình viên lại không thèm xin lỗi.

Warning Comments thường được mô tả bằng lời cảnh báo rằng một phần code nào đó chỉ có thể được một lập trình viên nhất định chạm vào. Ví dụ như bên dưới:

// Here be dragon - See Robert

// Great Sins against code
// begin here...

Đôi khi cảnh báo thực sự cần thiết, nhưng trong nhiều trường hợp, chúng chỉ đơn giản là dấu hiệu cho thấy một khu vực code này cần được tái cấu trúc.

Cảm ơn bạn đã đọc hết bài viết 🚀. Vì phần này khá dài, nên nó sẽ được chia nhỏ ra. Chúng ta sẽ đến tiếp với phần 2 Clean code #6: Viết comment (P2)


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí