Introduction
According to uncle bob comments should be avoided at all costs. Well written code should written in a way that is easy for other developers to understand. If developers follow the rules of writing clean methods as describe in Part 2 Methods avoiding comments makes even more sense.
Explaining Code
Developers sometimes write logic and try to explain the code through comments. These comments in most cases are not necessary as displayed in the code bellow.
// Verify if user has access to every module.
if ((user.Type == ADMINISTRATOR || user.Type == MANAGER) &&
user.IsActive) { }
if (user.HasAccessToWholeModule) { }
The code above in both cases has the same responsibility. The second case is a much more cleaner approach that doesn't need a comment to explain its purpose. Comments can also become obsolete if programmer's don't update them as the code evolves.
Useful Comments
In some cases it can be useful to create comments, but it is important to keep in mind that no comment is always better than having comments. Analyze the following code:
services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionScopedJobFactory();
var jobKey = new JobKey(JOB_NAME);
q.AddJob<HelloWorldJob>(opts => opts.WithIdentity(jobKey));
q.AddTrigger(opts =>
opts.ForJob(jobKey)
.WithIdentity(JOB_TRIGGER_NAME)
.WithCronSchedule("0/5 * * * * ?")); // run every 5 seconds
});
The code above has an example of middleware configuration of the open source job scheduling system library named quartz. It uses cron to define schedules and in this case it would make sense to add a comment to interpret the schedule.
Other comments might also be appropriate in code like:
- Important functionalities
- TODO explaining obsolete or pending items about a method.
- Alerts about long running process.
Excessive Comments
Many times I run into code with excessive comments. Programmers might think the code looks elegant with these comments, however they are redundant and not necessary. The code bellow has an example of excessive comments:
/// <summary>
/// User Class
/// </summary>
public class User
{
/// <summary>
/// User Type
/// </summary>
public string Type { get; set; }
/// <summary>
/// Verifies if user is active
/// </summary>
public bool IsActive { get; set; }
}
Regions
Regions in C# are sometimes used inside a method to "Improve Code Readability". Regions inside methods actually increases the size of the method and should be avoided at all costs. Regions could be used outside of methods to organize code, but that should be avoided too. In some cases where classes contains hundreds or thousands of lines of code it could make sense to have regions as shown in the following figure:
Conclusion
There are many other examples of comments that should be avoided not explored here. The main idea that you should be aware if you got to this point is to always avoid commenting code whenever possible. I find that having a concise external documentation about the system, requirements and architecture can also avoid many unnecessary comments in the code.
References
- Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin.
- Quartz
Top comments (6)
Those are documentation comments and while this is an example of an extremely bad and unhelpful documentation, they aren't excessive or redundant because they aren't there for people who can see the code, they are there for people reading the generated external documentation.
If you want your documentation to be as high quality as your code, then every class, method, etc should have useful well written documentation comments.
Dear Jay,
Thank you for your comment, as uncle bob likes to cite in his books many developers might not agree with all the rules and it's ok. With a couple of years of experience as a software developer in the .NET environment, I never ran into a scenario where I used external documentation generated from source code. If you work for an organization that requires external documentation like this then off course that would be necessary.
From a clean code point of view where methods and classes have single responsibilities, unit tests, etc. I don't agree with your statement that "every class, method, etc should have useful well written documentation comments".
You say you've never used external generated docs, but I'd bet you've read Microsoft's dotnet docs and those are autogenerated from the source code and its documentation comments.
To each their own, but in the decade I've been building .Net libraries and applications, well written documentation has been extremely useful, both as an asset for clients and as a knowledge store for future devs when brought onto a project.
My main point is that documentation comments and code comments aren't the same thing. The idea proposed by Uncle Bob and the like, that comments are bad and should be replaced with self describing code, applies to code comments, not documentation comments, because documentation comments aren't for people reading the code, they are for people reading the docs.
Hey Jay, makes sense for people reading the documents in applications that exposes the documentation to have comments in classes and methods. In these cases for external documents, I would consider them as part of the non-functional requirements.
Those external comments are used to generate OpenAPI documentation using Swagger.
Yes I agree, it does make sense to comment code to expose documents to others. I would consider this a non-functional requirement.