Monday, August 13, 2007 8:52 PM
One of the best things that you can do to give your code a long and happy life is to improve its readability. Lucky for you, readability is one of the simplest things to improve. There a tons a little tricks out there that can instantly make your code more maintainable, cleaner, and easier to read. In fact, we discussed some of these today during a code review and I'd like to share just a few of them with you...
Update 08/20/2007: I had so many great tips from the comments that, upon an excellent suggestion from mysterious "R", I decided to add them to the original post. Here they are:
Courtesy of Thomas Eyde
Replace boolean literals with named variables
Think back to the last time you saw one of those methods loaded down with boolean after boolean. All of those values made perfect sense when you wrote the method...six weeks ago. But, what about now?
adapter.OpenConnection(@"C:\data\records.mdb", true, false);
Do you remember what that 'true' represented? What about the 'false'? Is it still as clear as it was six weeks ago? Probably not. But what if you had used named variables in place of those literal booleans?
bool useIntegratedSecurity = true;
bool useConnectionPool = false;
adapter.OpenConnection(@"C:\data\records.mdb", useIntegratedSecurity, useConnectionPool);
Makes a little more sense now, doesn't It? We can tell at a glance that the second parameter tells us that we're using integrated security for authentication. And we can tell from a second glance that the third parameter tells us that we're not drawing from the pool for this connection.
Replace numerical literals with named constants
Ever seen one of those methods chock full of magic numbers that no one seems to know that they do but you? Sure, we all have. Here's a better one. Ever seen one of those methods chock full of magic numbers that even
you can't remember what they all do? Once again...we all have. In fact, here's one of those little gems right now...
Console.Write("Printing values...");
Console.Write(adapter.GetValue(0));
Console.Write(adapter.GetValue(1));
Console.Write(adapter.GetValue(2));
Console.Write(adapter.GetValue(3));
Console.Write("End values.");
So what's that first value that's being printed? Hmm, ok how about the second? Thought so. The Third? Fourth? That's what I thought. But, I'm sure you knew two weeks ago when you wrote it and that's all that matters...right? Wrong. Let's try to put some named values in there...
const int CompanyName = 0;
const int CustomerName = 1;
const int CustomerPhoneNumber = 2;
const int ProductName = 3;
Console.Write("Printing values...");
Console.Write(adapter.GetValue(CompanyName));
Console.Write(adapter.GetValue(CustomerName));
Console.Write(adapter.GetValue(CustomerPhoneNumber));
Console.Write(adapter.GetValue(ProductName));
Console.Write("End values.");
Now, what's that first value being printed? What about the second? Third? Fourth? It's a little bit easier this time around isn't it?
Replace indexers in nested for loops with meaningful variable names
i, j, and k. Every coder's favorite name for loop variables. Not that they're bad names, they're perfectly fine names. In fact I may name my next trio of gold fish those very name. But those are gold fish...not loop variables. Let's take a look at the following code and see how little sense it makes...
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
for (int k = 0; k < 100; k++)
{
alpha.Process(values[i][j][k]);
}
}
}
Three dimensions, three completely undescriptive variable names. Does anyone want to take a guess at what these dimensions represent? Didn't think so. But how about after we add some better names for the index variables?
for (int rows = 0; rows < 100; rows++)
{
for (int columns = 0; columns < 100; columns++)
{
for (int keys = 0; keys < 100; keys++)
{
alpha.Process(values[rows][columns][keys]);
}
}
}
What do you think now? Can you guess what we're looking at here. Do you have better ideas about what types of things we may be looking for?
These were three easy tricks that you can do to improve the overall readability of your code. Keep in mind that although they technically are refactorings, they do little to change the overall structure of your code. These are very low risk changes. These are simply aesthetic changes but notice how much of a difference they make to the overall quality to your code.
Simple changes, big improvements.