Stephen Freeman Rotating Header Image

September, 2008:

Why it pays to take the time to write readable code.

Just in case we still have to make the point:

There’s certainly evidence that that “exploratory” approach to computing is an important job skill. Beth Simon and Andy Begel’s recent series of papers on their study of new hires at Microsoft show that the first year of work is mostly spent understanding existing code, not writing new code.

From Mark Guzdial.

Husbanding willpower

I picked up the New Scientist for my in-flight reading on the way to JavaZone and came across a fascinating article.

For those who don’t have a subscription, it turns out that willpower is a limited resource, like exercising a muscle. Different people have different limits, but when they’ve used it up they need time to recover. Worse, the relevant part of the brain may also be worn out by making difficult decisions and coping with stress. This is why it’s a bad idea to try to reform all your habits at the same time, there isn’t enough mental strength to go round.

The implications for us Agilistas are interesting. It explains the value of ceremony and automation that we emphasise so much, they relieve us from wasting willpower on known practices. It also suggests a validation for pair programming in that it allows one member of the pair to recharge their motivational batteries whilst the other pushes on. Another interesting result, from Peter Gollwitzer at NYU, is that doing task breakdown for an activity helps to get it done,

Planning can turn a difficult conscious decision into an unconscious habit, which makes the whole process faster and more efficient without depleting energy levels.

which sound like a good reason to crack open another pack of index cards.

Two more relevant points. First, willpower takes physical energy. Spending long hours slumped in front of the keyboard means that much of that work will be done when the brain is too tired to think things through. Second, willpower can be strengthened by practice. Exercising self-control in one area can boost it in others, which suggests to me that the benefits of building a high-quality culture will be better than linear.

The research also reinforces Roy Osherove’s point on the difficulties of getting TDD adopted, even if we differ on the solution.

Perhaps this means that there could be a measure for the hidden costs of organisational drag, what Ivan Moore and Rachel Davies referred to as Gumption Traps. If just making it to your cubicle burns up a significant fraction of your store of willpower, then there’s less left for writing great systems; that’s why I think the regime at DEC SRC was so remarkable.

Perhaps it might also explain why so many geeks who write perfectly clean code live in such a mess.


P.S. The New Scientist web site currently includes this infinitely depressing story about how, in a world that can find nearly a $1G to save the banks, we can’t save the cod.

Fishing vessels on the Grand Banks of Newfoundland are this week destroying the best hope for years that the region’s cod fishery, once the world’s most abundant, might yet recover.

And at a meeting in Vigo, Spain, governments have rejected a simple measure that might have given the cod a fighting chance.

That’s why I can’t read it all the time.

The reactionary voice of TDD

So, by one reading of Roy’s posting, I appear to have become the reactionary voice of TDD, a sort of technical William F. Buckley, which is not something I aspire to.

The question is how to get all those developers to do TDD when, apparently, they don’t know the basics of software design. It seems the answer is to separate the two, to teach unit testing while ignoring the issue of code quality in the expectation that people will catch up in the end. I absolutely agree that it’s important not to overload students, especially after reading this paper1, but this solution doesn’t make sense to me.

My experience is that unit testing ill-structured code is an adventure in software callisthenics, requiring feats of special deviousness; Michael Feathers wrote a whole book about how to do it. Tools that slice through the runtime may sometimes be necessary, but dangerous power tools should only be used by trained staff2. This is fixing the wrong problem.

My suggestion is to start by improving the design skills of your team, that’s your biggest problem. There’s so much material available, all well-established; for example, you could buy a copy of Object Design and some index cards. There’s a catch, of course, in that this is not a shiny new technique so funding for actually training staff is harder to justify, but you know how to work around that.

In the meantime, write an automated build and some acceptance tests around the system—not for everything, but just enough to show that the application will do the basics when you start it up. For many teams, this would be a significant advance. When this has bedded in and the the team has begun to write objects that tell each other what to do, it will be time to move to a higher astral plane (my shamanic rates are quite reasonable) and start the first stumbling steps in TDD.

The alternative is to do TDD without understanding and, from what I’ve seen, that ends up with exactly what some people complain about, twice as much code for no benefit. My guess is that a brittle, incomprehensible tests suite will not survive the first deadline crisis.

The irony of all this is that, despite my apparently being part of a consultants’ cabal that is protecting its elitist interests3, this approach is likely to be cheaper since material on good OO design is a commodity nowadays and deferring the adoption of full-scale TDD will be less disruptive.


  1. via Mark Guzdial’s excellent blog
  2. I love this quotation from the article: And the number one most dangerous power tool in your wood shop is YOU.
  3. Is this where I turn into Obama?

Unpack the bag

There’s a common pattern where an object is constructed with a Context object that carries all the dependencies the new object might need. It’s often used, for example, with classes that package up domain behaviour based on lower-level services, something like this:

public class PriceReconciler {
  private final Context context;

  public PriceReconciler(Context context) {
    this.context = context;
  }

  public boolean isAvailable(Item item, Price price) {
     Location location =
        context.getLocationFinder().findLocationFor(item);
     SKU sku = location.lookup(item);
     return context.getCurrencyConverter()
                        .compare(price, sku.cost()) < 0;
  }
 // and so on...
}

Mary Poppins

Over time the Context gets used in more and more places, and acquires more and more contents to carry around. It starts to feel like Mary Poppins' carpet bag (there's an old cultural reference) that contains a roomful of furniture. When everything is available everywhere then developers will use what they have in scope and, pretty soon, there are implicit dependencies all over the domain layer.

A while ago, I was working with a class that used one of these context objects. The class was quite large so, to help us understand it, my pair and I extracted the services it used into fields:

public class PriceReconciler {
  private final LocationFinder locationFinder;
  private final CurrencyConverter currencyConverter;
  private final LooseChangeCollector looseChangeCollector;

  public PriceReconciler(Context context) {
    this.locationFinder = context.getLocationFinder();
    this.currencyConverter = context.getCurrencyConverter();
    this.looseChangeCollector =
      context.getLooseChangeCollector();
  }
 // and so on...
}

Doing this made clear that the class used only three of the many services available on the context. More interesting, it showed that the looseChangeCollector was only used once, in a method that turned out to be referenced just once—by a class that also had access to the context. Our extraction highlighted that this behaviour was in the wrong place, it didn't really have a relationship with the rest of PriceReconciler, so we moved it to its calling object and simplified the PriceReconciler. With just two dependencies, our
next step was to set them directly in the constructor

public class PriceReconciler {
  private final LocationFinder locationFinder;
  private final CurrencyConverter currencyConverter;

  public PriceReconciler(LocationFinder locationFinder,
                         CurrencyConverter currencyConverter)
 {
    this.locationFinder = locationFinder;
    this.currencyConverter = currencyConverter;
  }
 // and so on...
}

which made the PriceReconclier just a little easier to reuse since we'd narrowed its dependencies.

Kent Beck wrote recently about this tension between being concrete and abstract parameters. There obviously isn't a single answer, except to note that when two or three objects keep turning up together, there's probably a missing intermediate concept where some of the behaviour really belongs. The trick, when turning that concept into a type, is to give it a meaningful name so that it's hard to add features that don't belong.

Speaking in Oslo

I’m speaking at JavaZone in Oslo, on September 17th. I was so impressed last year that I managed to get back in. The topic will be Listening to Test Smells, which Nat and I have been raising for a while.

I’ll only be there until mid-afternoon Wednesday, so get in touch early if you want to meet up, and I’ll miss the remarkable ClubZone evening when the conference overflows into downtown Oslo.

Asian trip. Anyone interested?

I’ll be travelling for personal reasons to Beijing, Shanghai, Seoul, and Hong Kong in late October.

I’ve already been making enquiries, so if you’re interested in getting together then please drop me a line.