On a quest for the silver bullet..

Trustworthy methods

What constitutes a great method? It’s a method you can trust, a method that you understand by looking at its name, and it doesn’t have nasty side effects. It’s about software quality, and about spending less time coding defensively. Our methods should be trustworthy so that writing code gives us “least surprise, least paranoia” (coined by the good citizen-pattern). We want to write trustworthy code that is easy to interact with. Here are my guidelines for producing trustworthy methods.

Communication

The more I write code, the more I realize that understandability is one of the key aspects of writing code. Making myself understood. Writing readable code. In his book “Implementation Patterns”, Kent Beck identifies “Communication” as one of the three values “consistent with excellence in programming”.

We should spend more time thinking about what we want to communicate when we write code.

When it comes to naming methods, my rule of thumb is that you’re not supposed to have to look into a method in order to understand how to use it. By looking at the method name, maybe it’s parameters and return value, and considering its context (the class that encapsulates it), I should clearly understand what the method will do for me.

Communicate intent, and intent only

A good method name should communicate intent: What service do I offer, what will I do for you. On a collection-class, a method like

sort()

communicates it’s intent well. Given the concept of a collection, we understand that this will sort the items. Now what about this:

sortUsingQuickSort()

Still we communicate intent, but there are two problems here. We now have to consider how we want to sort the collection when we call this method. Wouldn’t it be better if the collection made this decision itself? The collection should be in a much better position to make that choice. And often we do not care about how, we just want it done. It’s important to make the choices as easy as possible for the consumer of your methods.

The second problem is that we reveal implementation details. In many cases this method says to much about the inner workings of it’s class. A well designed object oriented class, reveals as little as possible about it’s implementation details. We do not want to give away that information because we reserve the right to change the implementation of the sorting later.

No surprises

A method should do exactly what it tells me it will do. Nothing more, nothing less. There shall be absolutely no surprises! Consider this method on a collection:

int size()

I’m sure we all expect this method to return the number of elements in the collection. So if this method actually removed the last element in the collection, that would have been quite a surprise! And of course that would have been a recipe for disaster. Because “all surprises in our industry are bad surprises” (I think Kevlin Henney phrased that one).

This case is obvious, but believe me, I have seen some pretty nasty side effects in methods. Such side effects often appear when you do not consider what the method is supposed to do in general terms, you only think about what it will do for you right now. For instance if this collection-class for the moment only was used one place in your code, and you were two hours from deadline and needed this to work, instead of implementing a queue with a dequeue-method, you just removed the last element in the size()-method. Maybe something like this:

// Warning: example of stupid code 
while (collection.size()>0) { 
  handleElement(collection.getLast()); 
}

This is not the best example because the stupidity of this is so obvious, but there are lots and lots of similar examples that are more subtle but still just as stupid.

Make your methods as trustworthy as possible, do what you promise, but absolutely nothing more. State the intent, and stick to it.

- Tore Vestues

March 14th, 2008 at 20:51 (910)


Leave a Reply