Monday, November 19, 2012

BlogPost blogPost = BlogPostFactory.MakeBlogPost(NewBlogPostOptions.BlogPostWithAbsurdTitle)

Don't leak useless implementation details in your variable, method, or class names. Just don't.

Sure, the name may be accurate and true, but so what? I don't need to see the class name 5 times in one line - that just clutters up the place. It also makes it harder to see similarities in code and opportunities for refactoring. These kinds of names also go against the entire point of polymorphism: you don't need to know the type, just it's capabilities. Hungarian notation obviously falls into this category of cluttering up the place with implementation details. I rarely need to know the exact type or inner working of something. What I need to know is the intent.

There is one place where a name should leak implementation details though: choosing a strategy. Not just the Strategy Pattern, but even between different methods that all do the same thing but in a different way. I'm thinking of things like depthFirst vs breadthFirst, MaximizeBenefitStrategy vs MinimizeCostStrategy vs MinimizeRiskStrategy, or calculateLevenshteinDistance vs calculateJaroWinklerDistance. These seem like good implementation leaking names to me since when I choose one, I need to choose the exact details. Of course they could be wrapped in intention revealing names which would be used most of the time:

public double PercentSimilarTo(this string myself, string other)
    var longest = (double)Math.Max(myself.Length, other.Length);
    return EditDistanceCalculations.CalculateLevenshteinDistance(myself, other) / longest;

Try it for a few weeks and see what happens. I think that replacing implementation revealing names with intention revealing names is one of the easiest ways to improve code.

var p = new Bp()

Don't use abbreviations in your variable, method, or class names. Just don't.

Sure, you save 2 or 3 seconds, and a few characters on the screen, but so what? You, or whoever is looking through your code, loose even more time when you have to look around to find out that cs is an array of Customers. Then you have to spend time trying to figure out why you have this array. Are they delinquent customers? New customers? Customers who have a birthday today? What's the intent of this thing? This is especially bad with primitives or collections of primitives because they have even less inherent meaning. It's also bad when the same variable is used for multiple things. If cs is an array of customer indexes on one line, an array of page numbers on another, and x, y, and z coordinates for an airplane on another line then you can't give it a good name and it should be split into three separate variables: customerIndexes, pageNumbers, and airplaneCoordinate.

Worst names:

Bad names:

Good names:

A name is more than just a unique identifier: it's a way to express intent and meaning. The compiler doesn't care what you use - it's just as fine with zhqxv as it is with unwantedLocationNames - but I know which one I'd prefer.

I can only think of one reason to have a one character or abbreviated name: if it's a well known and commonly accepted part of that domain. Gui and hud may be acceptable names within a user interface domain and x and y sound acceptable when talking about cartesian coordinates. If you look at it a certain way, i and j could be considered valid names within the "looping through a collection with an index" domain, but even then, there's probably a better name.

Try it for a few weeks and see what happens. I think that replacing abbreviations with real, intention revealing names is one of the easiest ways to improve code.