DEV Community

AliReZa Sabouri
AliReZa Sabouri

Posted on • Edited on

Comments are not Evil: Beyond Self-Documenting Code 😈


Crafting exceptional code goes beyond functionality. It's about creating solutions that are readily understood by fellow developers, including your future self. This is achieved by a skillful marriage of well-written, self-documenting code and strategically placed comments.

While the importance of self-documenting code is widely recognized, there's sometimes a misconception that it eliminates the need for comments entirely. This article aims to emphasize that although self-documenting code is the bedrock of clarity, well-placed comments play a crucial role in providing the deeper 'why' that code alone can't always express.

I've often seen codebases that either lean too heavily on comments or neglect them entirely. This inspired me to share my thoughts on finding the right balance.

first, let's have a look to remind ourselves what is the Self-documenting code

Self-Documenting Code: The Strong Foundation

The foundation of clear code lies in meaningful choices that make the code itself communicate its purpose. This involves two key elements:

  • Meaningful Names: Choose variable and method names that are descriptive and illuminate their role within the code. Let's illustrate this with a simple example: instead of a cryptic variable name like x, consider using customerOrderTotal. This immediately conveys the variable's purpose.

  • Explanatory Method Names: Method names should clearly convey the action performed. For instance, opt for a name like ProcessPayment rather than a generic name like Calc. Imagine another developer reading your code – a well-chosen method name lets them instantly grasp the function's intent.


The Power of Comments: Explaining the 'Why'

While clear code explains the 'what' a section of code does, comments play a crucial role in unraveling the 'why':

  • Intentions Behind Complex Logic: If a code block implements intricate logic or algorithms that aren't immediately clear, a comment explaining the thought process behind it can be invaluable. This helps developers understand the reasoning and approach taken.

  • Edge Cases and Exceptions: Comments can highlight specific scenarios or edge cases that your code handles, especially those that might not be immediately obvious to someone reading the code for the first time. This ensures developers are aware of these potential situations.

  • Reasoning for Choices: Sometimes, you might choose a particular data structure, algorithm, or design pattern for a specific reason. A comment explaining this decision can be very helpful, especially if it's not the most typical approach. This fosters code clarity and knowledge sharing within the team.

Example:

/// <summary>
/// This method uses a binary search for efficiency because customer data 
/// is frequently searched. A standard linear search would be less performant 
/// in this scenario.
/// </summary>
List<Customer> FindCustomerByEmail(string email)
{
  // ... binary search implementation ...
}
Enter fullscreen mode Exit fullscreen mode

Clarity Beyond Names: The Need for Context

Even with the best intentions and carefully chosen names, there are times when code needs a bit more explanation to achieve genuine clarity. Let's illustrate this through an example:

public class Customer { 
  // ... other properties...
  public bool HasDiscount { get; set; } 
}

Enter fullscreen mode Exit fullscreen mode

Let's attempt to make this property name clearer:

public class Customer { 
  // ... other properties...
  public bool IsEligibleForDiscount { get; set; } 
}
Enter fullscreen mode Exit fullscreen mode

This change is definitely clearer. However, questions might still arise:

  • What factors EXACTLY determine eligibility (e.g., age, purchase history, subscription status)?
  • Are there multiple discount types with different eligibility criteria?

Where Comments Shine:

A short summary comment above the property can clarify this logic:

Example:

public class Customer { 
  // ... other properties...

  /// <summary>
  /// Indicates if the customer has spent over $500 in the last 6 months, 
  /// or holds a premium subscription.
  /// </summary>
  public bool IsEligibleForDiscount { get; set; } 
}

Enter fullscreen mode Exit fullscreen mode

Important Considerations ❗

  • Documentation: If you have robust project documentation that thoroughly explains the logic and conditions for eligibility, the comment might be redundant.

  • Code Structure: If eligibility logic is centralized in a single, well-named class or method, the comment might be less crucial, as that method would be the clear place to look for the rules. However, in more complex scenarios where eligibility logic might be scattered across different parts of the code, such a comment provides a crucial anchor point for developers.

  • Domain-Driven Rule of Thumb: As a simple rule for domain-driven design, consider adding comments whenever you have public setters that modify the internal state of your domain objects. This helps highlight potential side-effects and preserves the integrity of your domain model.


Best Practices for Effective Commenting

Here are six key practices to ensure your comments are truly beneficial:

  1. Purpose, Not Mechanics: The goal of comments is to illuminate the purpose of code, not simply rehash the steps it takes. Assume the reader understands the syntax of the programming language. Focus on the 'why' behind the code, not the 'how'.

  2. Add Value, Avoid Duplication: If the code itself is clear and self-explanatory, a comment might not be necessary. Don't add comments that simply repeat what the code already expresses.

  3. Clarity is King: Comments should make the code easier to understand, not introduce confusion through jargon or overly complicated explanations. Use clear and concise language that someone unfamiliar with the specific codebase can comprehend.

  4. Keep it Updated: Remember, comments, like code, need maintenance. Outdated comments can be misleading and do more harm than good. Regularly review your comments to ensure they accurately reflect the current code behavior.

  5. Brevity Matters: Extensive comments can be a sign that your code might be overly complex and could benefit from refactoring. Strive for clear and concise explanations that get straight to the point.

  6. Spotlight the Non-Obvious: Focus your comments on code that might not be self-evident to another developer. If the logic is intricate or there's a specific design choice involved, a comment explaining it can make a big difference.


The Art of Balance

The most maintainable code is a well-calibrated blend of the following:

  • Prioritize Self-Explanatory Code: Focus on clear naming conventions and well-organized code structure as your primary means of revealing the code's intent. Invest time in making the code itself as readable as possible.

  • Comment Strategically: Use comments to enhance understanding, not as a crutch for unclear code. Comments should illuminate the 'why' behind complex logic or design choices, not simply repeat what the code does.

By mastering these practices, you'll write code that is both clear and insightful, making the maintenance and collaboration processes far more effective. Your code will be a pleasure to work with, for both yourself and your fellow developers.

Let's keep the conversation going! Share your own commenting experiences and best practices in the comments below.

Top comments (3)

Collapse
 
mehrandvd profile image
Mehran Davoudi

Enjoyed very much :)

Collapse
 
sajjadhosseinpour profile image
Sajjad Hossein Pour

Thoroughly enjoyed your article. Well done!

Collapse
 
iialireza profile image
Alireza Arabshahi

Insightful. Thanks for sharing. 👍