“Code cleanup” is a phrase that sounds like it’s a lot of work. Well, sometimes it may be an arduous task, indeed. But that doesn’t mean it’s the way it should be. As with many things in software development—and in general life—it’s often more comfortable, less painful and more productive to do an unpleasant task every day, little by little than let it accumulate and become a monster.
That’s what today’s post is about. We’ll present seven simple code cleanup tasks that you can perform daily, to keep your codebase readable, easy to navigate, and maintain. We don’t necessarily expect you to perform all of the steps every day. On some days, you might be able to pull it off, but on others, it might be harder to do so.
Think of the seven tips you’ll read as a practical embodiment of the scouting principle: leave the code better than how you’ve found it. Let’s get started.
1. Getting Rid of Commented-Out Code
Getting rid of commented-out code is something easy to do, and it shouldn’t come as a surprise for anyone who’s a regular reader of this blog since we’ve already covered that topic before and not only a single time. We recommend you read at least one of those articles, but we’ll offer the short version here anyway.
Commented-out code is a source of distraction and cognitive load. Developers will see it and wondering whether that code is supposed to be used or not. It will get in the way of the useful code, forcing you to scroll through the screen in order to get to the function you need to read or edit. Commented-out code can also create problems when it’s eventually uncommented: the longer it stays commented-out, the less likely it is that it’s still right and fits the rest of the application.
What to do with the commented-out code? The answer will depend on the reason why the code was commented-out in the first place, and that varies.
- If the code was commented by fear of losing it, delete it. The version control system will remember it.
- Was the code commented-out to toggle a feature on and off for testing purposes? Feature flags and compiler directives are better alternatives.
- If the code was commented-out, but it shouldn’t have been, uncomment it, but first write a failing test to warn you if someone comments it again.
2. Adding or Updating XML Documentation to Public Members
The second tip is simple: before you call it a day, verify that all public members on every file you’ve touched have XML documentation tags. If some member lacks documentation, add it. Update the documentation where it’s outdated, incomplete, or otherwise inaccurate.
3. Reviewing Names of Variables, Parameters, etc
The third tip of the list: before submitting your work for the day, do a quick review of the names you’ve picked for your software artifacts. If you see anything that could use some improvement, improve it. And since “improve it” is as vague as it is unhelpful, here you have a small list of practical steps you can take during your naming review:
- Eliminate single-letter variables. Unless we’re talking about control variables in a for-loop or short lambda-expressions, single-letter variable names are awful for code clarity and especially searchability.
- Ensure the names follow widespread C#/.NET conventions, e.g., PascalCase for type names, properties and methods, camelCase for parameters and locals, etc.
- Avoid the Hungarian Notation system when naming variables, especially the System Hungarian Notation variant.
- Use acronyms or other types of abbreviations only when they’re widely known. By “widely known,” we mean not only at a national or global level. If the acronym has widespread adoption in your industry or domain (or even just inside your company), then use it at will.
Naming is one of the hardest things in Computer Science, but that doesn’t mean there aren’t tried-and-true practices you can follow that will make your code cleaner.
4. Checking Whether the Code Follows Team Standards
The step here is also very simple: to verify whether the code on the files you’ve touched adhere to the coding standards practiced by the team. In a professional software team, there shouldn’t be such a thing as “Alice’s code” or “Bob’s style.” The team has to agree on a coding standard.
A coding standard covers not only naming but also things like indentation, code formatting, whether to use or not use type inference, whether to use type aliases or the full framework names for the types, and so on.
5. Getting Rid of Unnecessary Indentation Levels
Code with too many indentation levels gives origin to a problem sometimes called the Arrow Anti-Pattern. But why would excessive indentation be a problem?
For starters, it harms readability. Each new “if” or “else” you come through adds more weight to the cognitive load you have to keep in order to make sense of the code you’re reading. Also, code like that becomes a pain when you have to split your screen in order to review some code, solve a merge conflict, or keep your tests side-by-side with your production code when doing TDD.
Finally, code with too many levels will have a higher cyclomatic complexity, which makes the code harder to understand, besides increasing the number of test cases necessary to cover all the possible paths the function can go through.
So, what about the alternatives? One easy measure is to combine multiple “ifs” into one, when possible. So, instead of this:
if (someCondition) if (otherCondition) // do the thing;
You could write:
if (someCondition && otherCondition) // do the thing
The example may seem contrived, but I’ve seen code like this in real life before. Another solution is to use guard clauses to check for invalid situations, and then return or throw early. So, don’t write code like in the following example:
public void SomeMethod(Foo foo, Bar bar, string name, DateTime date) { if (foo != null) if (bar != null) if (!string.IsNullOrWhiteSpace(name)) if (date.Date <= DateTime.Today) // do the thing; }
Rather, check first that the arguments meet the necessary criteria for the method to do its work (in other words, the preconditions). If they don’t, you return or throw:
public void Metodo(Foo foo, Bar bar, string name, DateTime date) { if (foo == null) throw new ArgumentNullException(nameof(foo)); if (bar == null) throw new ArgumentNullException(nameof(bar)); if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException($"{nameof(name)} should be a valid, non-empty string."); if (date.Date > DateTime.Today) throw new ArgumentOutOfRangeException(nameof(date)); // now, do the thing! }
Finally, when possible, turn an indentation level into a dedicated function. You’ve already seen that you can combine three nested “ifs” into a single if, with three conditions. You can go one step further and extract that to its own function. Bonus points if the same conditions appear again in the code since then your new function will remove code duplication.
The same applies to for, foreach and while loops. When possible, remove them to a dedicated method or use LINQ to replace the loop with the equivalent functional style code.
6. Reviewing Spelling
This one might seem out-of-place, but it’s not. Believe it or not, spelling in code is important, as we’ve already said again and again. Spelling mistakes in code will cause problems with Intellisense and make the code less readable. They can also alienate the readers of the code and even cause potential embarrassment for the company in front of prospective new employees, clients, or even competitors.
By now, you know the drill, right? Before making your code a part of the mainline, make sure it doesn’t have spelling mistakes.
7. Removing Trivial Code Duplication
You’ve probably seen this coming. After all, code duplication is the bane of software engineering. Virtually every major principle or law in software development has something to do with keeping duplication at a minimum. The advice here is as simple as it can get: spotted some code duplication? If it’s easy to do it, remove it on the spot.
Keep in mind that we’re not talking here about hard duplication removal, the type that requires major refactoring. Nope. If it takes more than 10 minutes, you should still do it, but not as part of your daily cleanup routine.
Code Cleanup: You Don’t Have to Do It Alone
Code cleanup isn’t the easiest of tasks. Even our list of seven simple, low-hanging-fruit type of clean-up tasks could result in some reasonably labor-intense tasks. But I bring good news. There are tools you can use to make all of this dramatically easier for you.
First, your good old friend Visual Studio comes packaged with some automatic formatting features that you can use to do some basic formatting. A tool like StyleCop can ensure your style guide is followed to the letter. You can even make it fail the build on violations if you feel like it.
We couldn’t part ways without mentioning SubMain’s offerings, GhostDoc and CodeIt.Right. GhostDoc is a documentation tool that, among other things, can automatically generate XML documentation tags for you based on your code. You’ll probably have to change and adapt some of the generated descriptions, sure. But just having that bootstrap will save you a lot of time.
CodeIt.Right is an automatic code review tool that checks your code against a set of rules. Its rules can help you with most of the steps we’ve just shown you. It will catch commented-out code, spelling errors, and enforce your coding standard.
Start your code clean-up routine ASAP! Thanks for reading, and see you next time.
Learn more how CodeIt.Right can help you automate code reviews and improve the quality of your code.
1 Comment. Leave new
Is it possible to get GhostDoc to generate comments using a type alias instead of full framework names?