Posts Tagged ‘tdd’

We really are an arrogant, opinionated bunch, aren’t we? We work in an industry where there aren’t any right answers. We pretend what we do is computer “science”. When in reality, its more art than science. It certainly isn’t engineering. Engineering suggests an underlying physics, mathematical models of how the world works. Is there a mathematical model of how to build software at scale? No. Do we understand the difference between what makes good software and bad software? No. Are there papers with published proofs of whether this idea or that idea has any observable difference on written software, as practised by companies the world over? No. It turns out this is a difficult field: software is weird stuff. And yet we work in an industry full of close-minded people, convinced that their way is The One True Way. It’s not science, its basically art. Our industry is dominated by fashion.

Which language we work in is fashion: should we use Ruby, or Node.js or maybe Clojure. Hey Go seems pretty cool. By which I mean “I read about it on the internet, and I’d quite like to put it on my CV so can I please f*** up your million pound project in a big experiment of whether I can figure out all the nuances of the language faster than the project can de-rail?”

If it’s not the language we’re using, its architectural patterns. The dogma attached to REST. Jesus H Christ. It’s just a bunch of HTTP requests, no need to get so picky! For a while it was SOA. Then that became the old legacy thing, so now it’s all micro-services, which are totally different. Definitely. I read it on the internet, it must be true.

Everyone has their opinions. Christ, we’ve got our opinions. Thousands of blogs and wankers on twitter telling you what they think about the world (exactly like this one) As if one person’s observations are useful for anything more than being able to replicate their past success, should you ever by mistake find yourself on their timeline from about six weeks ago.

For example: I wrote a post recently about pairing, and some fine specimen of internet based humanity felt the need to tell me that people who need to pair are an embarrassment to the profession, that we should find another line of work. Hahaha I know, don’t read the comments. Especially when it’s in reply to something you wrote. But seriously now, is it necessary to share your close minded ignorance with the world?

I shouldn’t get worked up about some asshat on the internet. But it’s not just some asshat on the internet. There are hundreds of thousands of these asshats with their closed minds and dogmatic views on the world. And not just asshats spouting off on the internet, but getting paid to build the software that increasingly runs all our lives. When will we admit that we have no idea what we’re doing. The only way to get better is to learn as many tools and techniques as we can and hopefully, along the way, we’ll learn when to apply which techniques and when not to.

For example, I’ve worked with some people that don’t get TDD. Ok, fine – some people just aren’t “test infected”. And a couple of guys that really would rather gut me and fry my liver for dinner than pair with me. Do I feel the need to evangelise to them as though I’ve just found God? No. Does it offend me that they don’t follow my religion? No. Do I feel the need to suicide bomb their project? No. Its your call. Its your funeral. When I have proof that my way is The One True Way and yours is a sham, you can damn well bet I’ll be force feeding it to you. But given that ain’t gonna happen: I think we’re all pretty safe. If you don’t wanna pair, you put your headphones on and disappear into your silent reverie. Those of us that like pairing will pair, those of us that don’t, won’t. I’m fine with that.

The trouble is, in this farcical echo chamber of an industry, where the lessons of 40 years ago still haven’t been learnt properly. Where we keep repeating the mistakes of 20 years ago. Of 10 years ago. Of 5 years ago. Of 2 years ago. Of last week. For Christ’s sake people, can we not just learn a little of what’s gone before? All we have is mindless opinion, presented as fact. Everyone’s out to flog you their new shiny products, or whatever bullshit service they’re offering this week. No, sorry, it’s all utter bollocks. We know less about building decent software now than we did 40 years ago. It’s just now we build a massive amount more of it. And it’s even more shit than it ever was. Only now, now we have those crazy bastards that otherwise would stand on street corners telling me that Jesus would save me if only I would let him; but now they’re selling me scrum master training or some other snake oil.

All of this is unfortunately entirely indistinguishable from reasoned debate, so for youngsters entering the industry they have no way to know that its just a bunch of wankers arguing which colour to paint this new square wheel they invented. Until after a few years they become as jaded and cynical as the rest of us and decide to take advantage of all the other dumb fools out there. They find their little niche, their little way of making the world a little bit worse but themselves a little bit richer. And so the cycle repeats. Fashion begets fashion. Opinion begets opinion.

There aren’t any right answers in creating software. I know what I’ve found works some of the time. I get paid to put into practice what I know. I hope you do, too. But we’ve all had a different set of experiences which means we often don’t agree on what works and what doesn’t. But this is all we have. The plural of anecdote is not data.

All we have is individual judgement, borne out of individual experience. There is no grand unified theory of Correct Software Development. The best we can hope to do is learn from each other and try as many different approaches as possible. Try and fail safely and often. The more techniques you’ve tried the better the chance you can find the right technique at the right time.

Call it craftsmanship if you like. Call it art if you like. But it certainly isn’t science. And I don’t know about you, but it’s a very long time since I saw any engineering round these parts.

Read Full Post »

A couple of weeks ago I ran a “TDD Against the Clock” session. The format is simple: working in pairs following a strict red-green-refactor TDD cycle we complete a simple kata. However we add one key constraint: the navigator starts a five minute timer. As soon as the five minutes is up:

  • If the code compiles and the tests are green, commit!
  • Otherwise, revert!

Either way, the pairs swap roles when the timer goes off. If the driver completes a red-green-refactor cycle faster than five minutes, they can commit ahead of time but the roles still swap.

The kata we chose for this session was the bowling kata. This is a nice, simple problem that I expected we could get a decent way through in each of the two 45 minute sessions.

Hard Time

The five minute time constraint sounds fiendish doesn’t it? How can you possibly get anything done in five minutes? Well, you can, if you tackle something small enough. This exercise is designed to force you to think in small increments of functionality.

It’s amazing how little you can type in five minutes. But if you think typing speed is the barrier, you’re not thinking hard enough about the right way to tackle the problem. There comes a point in the bowling kata where you go from dealing with single frames and simple scores to spares (or strikes) for the first time. This always requires a jump because what you had before won’t suit what you need now. How to tackle this jump incrementally is part of the challenge when working within a five minute deadline. One of our group had an idea but knew it was tough to get it done in five minutes. He typed like a demon trying to force his solution in: he still ran out of time. Typing speed is not the problem (no matter how much it seems like it is). You need a better approach, you need to think more not type more.

Good Behaviour

After a few cycles, we found hardly anybody hit the 5 minute deadline any more. It’s fascinating how quickly everyone realised that it was better to spend a 5 minute cycle discussing than to get lost half-way through a change and end up reverting. Similarly, when you find the change you wanted to make in this cycle is too hard or too time consuming, it’s better to throw away what you have, swap pairs and refactor before you try and write the failing test again.

These are all good behaviours that are useful in day-to-day life, where it’s all too easy to keep chasing down a rat hole. Learning to work in small, independent increments and making that a subconscious part of how you work will make you a better programmer.

Wrong School

The biggest trouble we found is that the bowling kata isn’t well suited to what I consider “normal”, outside-in TDD (London School TDD). Most of the time I use TDD as a design tool, to help me uncover the right roles and responsibilities. However, with the bowling kata the most elegant solution is the one Uncle Bob drives towards, which is just simple types with no object modelling.

This is fine for an algorithm like scoring a game of bowling, which has an ultimate truth and isn’t likely to change. But in the normal day-to-day world we’re designing for flexibility and constant change. This is where a good object model of the domain makes things easier to reason about and simpler to change. This is typically where outside-in TDD will help you.

A couple of the group were determined to implement an OO version of the bowling kata. It isn’t easy as it doesn’t lend itself naturally to being built incrementally towards a good object model. However, with enough stubbornness it can be done. This led to an interesting discussion of whether you can TDD algorithms and whether TDD is better suited to problems where an object model is the desired outcome.

Obviously you can TDD algorithms incrementally, whether it’s worthwhile I’m not so sure.  Typically you’re implementing an algorithm because there is a set of rules to follow. Implementing each rule one at a time might help keep you focussed, but you always need to be aware of the algorithm as a whole.

Using TDD to drive an OO design is different. There can be many, similarly correct object models that vary only by subtle nuances. TDD can help guide your design and choose between the nuances. While you still need to think of the overall system design, TDD done outside-in is very deliberately trying to limit the things you need to worry about at any given stage: focus on one pair of interactions at a time. This is where TDD is strongest: providing a framework for completing a large task in small, manageable increments.

Even if the problem we chose wasn’t ideal, overall I found the TDD against the clock session a great way to practice the discipline of keeping your commits small, with constant refactoring, working incrementally towards a better design.

How do you move a mountain? Simply move it one teaspoonful at a time.


Read Full Post »

Whether or not you write integration tests can be a religious argument: either you believe in them or you don’t. What we even mean by integration tests can lead to an endless semantic argument.

What do you mean?

Unit tests are easy to define they test a single unit: a single class, a single method, make a single assertion on the behaviour of that method. You probably need mocks (again, depending on your religious views on mocking).

Integration tests, as fas as I’m concerned, mean they test a deployed (or at least deployable) version of your code, outside in, as close to what your “user” will do as possible. If you’re building a website, use Selenium WebDriver. If you’re writing a web service, write a test client and make requests to a running instance of your service. Get as far outside your code as you reasonably can to mimic what your user will do, and do that. Test that your code, when integrated, actually works.

In between these two extremes exist varying degrees of mess, which some people call integration testing. E.g. testing a web service by instantiating your request handler class and passing a request to it programmatically, letting it run through to the database. This is definitely not unit testing, as it’s hitting the database. But, it’s not a complete integration test, as it misses a layer: what if HTTP requests to your service never get routed to your handler, how would you know?

What’s the problem then?

Integration tests are slow. By definition, you’re interacting with a running application which you have to spin up, setup, interact with, tear down and clean up afterwards. You’re never going to get the speed you do with unit tests. I’ve just started playing with NCrunch, a background test runner for Visual Studio – which is great, but you can’t get it running your slow, expensive integration tests all the time. If your unit tests take 30 seconds to run, I’ll bet you run them before every checkin. If your integration tests take 20 minutes to run, I bet you don’t run them.

You can end up duplicating lower level tests. If you’re following a typical two level approach of writing a failing integration test, then writing unit tests that fail then pass until eventually your integration test passes – there is an inevitable overlap between the integration test and what the unit tests cover. This is expected and by design, but can seem like repetition. When your functionality changes, you’ll have at least two tests to change.

They aren’t always easy to write. If you have a specific case to test, you’ll need to setup the environment exactly right. If your application interacts with other services / systems you’ll have to stub them so you can provide canned data. This may be non-trivial. The biggest cost, in most environments I’ve worked in, with setting up good integration tests is doing all the necessary evil of setting up test infrastructure: faking out web services, third parties, messaging systems, databases blah blah. It all takes time and maintenance and slows down your development process.

Finally integration tests can end up covering uninteresting parts of the application repeatedly, meaning some changes are spectacularly expensive in terms of updating the tests. For example, if your application has a central menu system and you change it, how many test cases need to change? If your website has a login form and you massively change the process, how many test cases require a logged in user?

Using patterns like the page object pattern you can code your tests to minimize this, but it’s not always easy to avoid this class of failure entirely. I’ve worked in too many companies where, even with the best of intentions, the integration tests end up locking in a certain way of working that you either stick with or declare bankruptcy and just delete the failing tests.

What are the advantages then?

Integration tests give you confidence that your application actually works from your user’s perspective. I’d never recommend covering every possible edge case with integration tests – but a happy-path test for a piece of functionality and a failure-case gives you good confidence that the most basic aspects of any given feature work. The complex edge cases you can unit test, but an overall integration test helps you ensure that the feature is basically integrated and you haven’t missed something obvious that unit tests wouldn’t cover.

Your integration tests can be pretty close to acceptance tests. If you’re using a BDD type approach, you should end up with quite readable test definitions that sufficiently technical users could understand. This helps you validate that the basic functionality is as the user expects, not just that it works to what you expected.

What goes wrong?

The trouble is if integration tests are hard to write you won’t write them. You’ll find another piece of test infrastructure you need to invest in, decide it isn’t worth it this time and skip it. If your approach relies on integration tests to get decent coverage of parts of your application – especially true for the UI layer – then skipping them means you can end up with a lot less coverage than you’d like.

Some time ago I was working on a WPF desktop application – I wanted to write integration tests for it. The different libraries for testing WPF applications are basically all crap. Each one of them failed to meet my needs in some annoying, critical way. What I wanted was WebDriver for WPF. So I started writing one. The trouble is, the vagaries of the Windows UI eventing system mean this is hard. After a lot of time spent investing in test infrastructure instead of writing integration tests, I still had a barely usable testing framework that left all sorts of common cases untestable.

Because I couldn’t write integration tests and unit testing WPF UI code can be hard, I’d only unit test the most core internal functionality – this left vast sections of the WPF UI layer untested. Eventually, it became clear this wasn’t acceptable and we returned to the old-school approach of writing unit tests (and unit tests alone) to get as close to 100% coverage as is practical when some of your source code is written in XML.

This brings us back full circle: we have good unit test coverage for a feature, but no integration tests to verify that all the different units are hanging together correctly and work in a deployed application. But, where the trade-off is little test coverage or decent test coverage with systematic blindspots what’s the best alternative?


Should you write integration tests? If you can, easily: yes! If you’re writing a web service, it’s much easier to write integration tests for than almost every other type of application. If you’re writing a relatively traditional, not too-javascript-heavy website, WebDriver is awesome (and the only practical way to get some decent cross-browser confidence). If you’re writing very complex UI code (WPF or JavaScript) it might be very hard to write decent integration tests.

This is where your test approach blurs with architecture: as much as possible, your architecture needs to make testing easy. Subtle changes to how you structure your application might make it easier to get decent test coverage: you can design the application to make it easy to test different elements in isolation (e.g. separate UI layer from a business logic service); you don’t get quite fully integrated tests, but you minimize the opportunity for bugs to slip through the cracks.

Whether or not you write integration tests is fundamentally a question of what tests your architectural choices require you to write to get confidence in your code.

Read Full Post »

Newcomers to TDD ask some interesting questions, here’s one I was asked recently: testing private methods is bad, but why?

How did we get here?

If you’re trying to test private methods, you’re doing something wrong. You can’t get to TDD nirvana from here, you’re gonna have to go back.

It all started with an innocuous little class with an innocuous little method. It did one little job, had a nice little unit test to verify it did its thing correctly. All was right with the world. Then, I had to add an extra little piece of logic. I wrote a test for it, changed the class until the test passed. Happy place. Then I started refactoring. I realised my little method, with its handful of test cases was getting quite complicated, so I used the extract method refactoring and boom! I have a private method.

While simple when I extracted it, another couple of corner cases and this private method evolves into quite a complicated piece of code – which now I’m testing one level removed: I’m testing the overall functionality of my outer method, which indirectly tests the behaviour of the private method. At some point I’m going to hit a corner case that’s quite awkward to test from the outside, it’d be so much easier if I could just test the private method directly.

What not to do

Don’t use a test framework that let’s you test private methods. Good God, no. For the love of all that is right with the world step away from the keyboard.

What to do instead

This is a prime example of your tests speaking to you. They’re basically shouting at you. But what are they saying?

Your design stinks!

If you need to test a private method – what you’re doing wrong is design. Almost certainly, what you’ve identified in your private method is a whole new responsibility. If you think about it carefully, it probably isn’t anything to do with what your original class is. Although your original class might need renaming to make that obvious. That’s ok, too. That’s incremental design at work.

An example would help about now

Say I started off with a Portfolio class – it has a bunch of Assets in it, each of which has a Value. So I can implement a Portfolio.GetValue() to tell me how much it’s all worth. But then I start dealing with weird corner cases like opening or closing prices. And what do I mean by value, what I could sell it for, right now? Or perhaps there’s some foreign currency conversion to do, or penalty clauses for early exit, how does all that get factored in?

Before too long, GetValue() has a fairly large piece of logic, which I extract into GetSpotSalePrice(Asset). This method is then hairy enough to need testing, so it’s pretty clear that my design stinks. The deafening din of my tests, finally persuades me to extract GetSpotSalePrice(Asset) into another class, but here’s the million dollar question: which?

What not to do – part 2

For the love of SOLID, don’t put it in a AssetSalePriceCalculator, or a SalePriceManager. This is the number one easy mistake to make – you can follow TDD and ignore decent OO design and still end up with a steaming turd pile of horribleness.

NounVerber class is always a design smell. Just stop doing it. Now. I mean it. I’m watching you. I will hunt you down and feed you to the ogre of AbstractSingletonProxyFactoryBean.

What should I do then?

The answer might seem obvious, but to too many people starting out doing TDD and half-decent design – it isn’t at all obvious. The method needs to move to a class where that responsibility makes sense. In our example, it’s crushingly obvious this is really a method on Asset – it even passes one in. If your method has one class parameter and uses a bunch of data from that class, you can bet your bottom dollar you’re suffering feature envy. Sort your life out, apply the method move refactoring. Go live happily ever after.


Why shouldn’t you test private methods? Because the fact you’re asking the question means the method shouldn’t be private – it’s a piece of independent behaviour that warrants testing. The hard choice, the design decision, is where you stick it.



Read Full Post »

How often do you commit? Once a week? Once a day? Once an hour? Every few minutes? The more often you commit, the less likely you are to make a mistake.

I used to work with a guy who reckoned you should commit at least every 15 minutes. I thought he was mad. Maybe he is. But he’s also damned right. I didn’t believe it was possible: what can you actually get done in 15 minutes? At best, maybe you can write a test and make it pass. Well good! That’s enough. If you can write a test and make it pass in 15 minutes, check that sucker in! If you can’t: back it the hell out.

But I’ll never get anything done!

Sure you will, you just need to think more. Writing software isn’t about typing, it’s about thinking. If you can’t see a way to make a step in 15 minutes, think harder.

Chase the Red

One of my oft-used anti-patterns is to “chase the red”. You make one change, delete a method or class you don’t want – and then hack away, error by error, until the compiler is happy. It might take 5 minutes. It might take a week.

It’s very easy to get sucked into this pattern – you think you know where you want to get to: I have a method that takes a string – maybe it’s a product SKU from the warehouse; I want to replace it with a StockUnit which has useful functionality on it. Simples: change the signature of the method to accept StockUnit instead of string and follow the red, when the compiler’s happy: I’m done.

Trouble is – how do I know that every calling method can change? Maybe I think I know the code base and can make a reasonable guess. Maybe I’m even right. But it’s unbelievably easy to be wrong. I might even check all references methodically first, but until the code’s written – it’s just a theory. And you know what they say about the difference between theory and practice.

Is there a different way? What if I add a new method that accepts a StockUnit and delegates to the original method? I can test drive adding the new method, commit! I can go through each reference, one by one: write a failing test, make it pass by calling the new method, commit! Step-by-step, the code compiles and the tests pass every step of the way.

What happens if I hit something insurmountable half way? Where I am is a mess, but it’s a compiling, green mess. If I decide to back out I can revert those commits. Or refactoring tools can inline the method and automatically remove half the mess for me. But the critical thing is, every step of the way I can integrate with the rest of the team, and all the tests pass in case I hit something unexpected.

Merge Hell

The trouble with long running branches (and I include in that your local “branch” that you haven’t committed for two weeks!) is that the longer they run the harder they are to integrate. Now sure, git makes it easier to manage branching & merging – but you still have to do it. You still have to push & pull changes regularly – let others integrate with you and integrate with others as often as you can.

The likelihood of you having merge problems increases rapidly the longer your branch is open. If it’s 15 minutes and one test, you know what? If you have a merge problem, you can throw it away and redo the work – its only 15 minutes!

Just keep swimming!

But if you’ve been working for days and you hit merge hell, what do you do? You’re forced to wade through it. What you’re doing is chasing the red in your version control system. You’ve adopted an approach that gives you no choice but to keep on hacking until all the red merge conflict markers are gone from your workspace. If it takes 5 minutes or 5 days, you’ve got to keep going because you can’t afford to lose your work.

The kicker is by the time you’re done merging and everything compiles and works again, what’s the betting some other bugger has jumped in with another epic commit? Off we go again. You’re now in a race to try and merge your steaming pile before anyone else gets in. This is a ridiculous race – and who wins? Nobody, you’re still a loser.

Instead, if you adopt the 15 minute rule, you write a test, make it pass, check it in and push to share with everyone else. Little and often means you lose little time to merge conflicts and instead let your version control system do what it’s good at*: merging changes!

* doesn’t apply to those poor suckers using TFS, sorry

Brain Fade

An interesting side effect of a short cycle time is that you limit the damage periods of brain fade can do. I dunno about you, but there are times when I really shouldn’t be allowed near a keyboard. The hour after lunch can be pretty bad – a full belly is not good for my thinking. The morning after the night before: it’s best if you keep me away from anything mission critical.

The trouble is, if I have a multi-day branch open I’m almost guaranteed to hit a period of brain fade. Because I’m not committing, when my head clears and I realise I’ve screwed up I can’t just revert those commits or throw my branch away entirely – I have to try and unpick the mess I just made from the mess I already had. It’s incredibly hard to be disciplined and tidy when you’re wading in excrement.

We all make mistakes – but version control gives me an overview of what I did, without relying on my flaky memory. Maybe I’ve gone completely the wrong way and can unpick parts of what I’ve done, maybe I got lucky and some commits were half-way decent – I can cherry pick those and start a new branch. Without version control I’d be flapping around in an ungodly mess trying to figure out how to keep the good bits without just binning everything. All the time trying to explain to the project manager how I’m 90% done! No, really! Nearly there now!


Version control is an invaluable tool that we must learn to use properly. It takes discipline. It doesn’t come naturally. If you’ve never worked in such short cycles, work through a kata committing regularly. Our natural instinct is to type first and think later. Stop! Think about how you can make an increment in 15 minutes and do that. If you can’t: revert!

Read Full Post »

Writing good software is all about getting feedback, quickly. Does it compile? Does it function? Does it build? Does it deploy? Does it do what the customer wanted? Does it actually work? Every step of the way we have feedback loops, to improve the software. The faster these feedback loops are, the faster the software improves.


Don’t you hate waiting for your code to compile? Or, if you use a language from this century: do you remember back in the olden days when you had to wait for the compiler? Until recently, I’d actually forgotten that incremental compilers are a relatively new invention. I remember when JBuilder (my IDE of choice back in those distant times) first introduced me to incremental compilation – it was something of a revelation! You mean, I don’t have to hit compile? It just does it? In the background? Like magic?!

A few years ago I joined a company who had something of a byzantine build process. As was the fashion at the time, they used ant for their build. Unfortunately, nobody had told them that Eclipse could also compile code. So all code was built with ant. Made a change? Run the ant build to build the relevant library (may require guesswork). Copy it (by hand) to the app server. Quickly restart WebSphere (note: not quick). Test. Lather. Rinse. Repeat. Die of boredom.

Eventually, I replaced this with an Eclipse workspace that could run the application. No more build step. No more copying things by hand. No more mistakes. No more long delays in getting feedback.

Just recently I started working with C++ again after nearly a decade in byte code / interpreted languages. I’d actually forgotten what it was like to wait for code to compile. I’d got so used to working in Eclipse where you press Go and Things Happen(tm). Now instead I have to wait for a build before I can do anything. Every little change involves minutes of my life waiting for Visual Studio.

Then, if I’m really lucky – it will even compile! Remember when your IDE didn’t give you little red squiggles or highlight broken code? How fast is that feedback loop now? Before I’ve even finished typing the IDE is telling me I’m a moron and suggesting how to fix it. Assuming my code compiles, next I run the gauntlet of linking. Normally that means some godawful error message that googling just gives decade old answers and stack overflow posts that might as well be discussing religion.


I suspect this is why TDD is less common in the C++ world. Not only does the language feel ill-suited to doing TDD (to be honest, it feels ill-suited to writing software at all), but if you have to wait minutes after each change – TDD just doesn’t work.

  • Write a failing test
  • Wait minutes for the compiler to check your work, maybe go for a cuppa
  • Write code to make the test pass
  • Wait minutes for the compiler to check your work, perhaps its lunchtime?
  • Refactor

Actually, scrap the last step – since C++ is basically entirely devoid of automated refactoring tools – just leave whatever mess you’ve created because it’s about as good as it will get.

But with a red, green, refactor cycle that takes approximately 2.6 hours – it would be impossibly slow. No wonder TDD happens less.


I’ve been arguing recently about whether pairing or code review is the best way to improve code quality. I always used to be a huge believer in code review – I’d seen it have a massive impact on code quality and really help the team learn both the code and how to code better.

But now, after spending months pairing day in day out – I think pairing is better in every conceivable way than code review. Why? Because it’s so much more immediate. How many times have you heard feedback from code review getting left because “we don’t have time right now” or “we’ll come back to that just as soon as we’ve got this release out”.

But with pairing, you have your reviewer right there offering feedback, before you’ve even finished writing the line of code. Just like your modern IDE – giving you feedback before you’ve even had chance to get it wrong. And, just like the IDE, if the smart ass sitting next to you thinks he knows better, pass over the keyboard and let him show you.

This is just impossible with code review. The feedback cycle is necessarily much slower and, worse, it’s too easy to ignore. You can add a story to the backlog to fix code review comments. You can’t so easily add a story to the backlog to make the argumentative bloke next to you shut up! (More’s the pity, sometimes)

But either way – whether you get feedback from code review or pairing, the important thing is to get feedback. If you’re not getting feedback: you’re not learning and neither you nor your code are improving.

Read Full Post »

Software grows organically. One line at a time, one change at a time. These changes soon add up. In an ideal world, they add up to a coherent architecture with an intention revealing design. But sometimes software just grows hairy – full of little details that obscure the underlying logic. What makes software hairy and how can we stop it?

Hairy code

Generally code starts out clean – brand new, shiny code. But each time you make a change that doesn’t quite fit the original design you add a hair – a small, subtle detail. It doesn’t detract from the overall purpose of the code, it just covers a specific detail that wasn’t thought of originally. One hair on its own is fine. But then you add another, and another, and another. Before you know it, your clean, shiny code is covered in little hairs. Eventually code becomes so hairy you can’t even see the underlying design any more.

Let’s face it, we’re all basically maintenance programmers. How many of us actually work on a genuinely greenfield project? And anyway, soon after starting a greenfield project, you’re changing what went before and you’re back into maintenance land. We spend most of our time changing existing code. If we’re not careful, we spend most of our time adding new hairs.

The simplest thing

When changing existing code, there’s a temptation to make the smallest change that could possibly work. Generally, it’s a good approach. Christ, TDD is great at keeping you focused on this. Write a test, make it pass. Write a test, make it pass. Do the simplest thing that could possibly work. But, you have to do the refactor step. “Red, green, refactor“, people. If you’re not refactoring, your code’s getting hairy. If you’re not refactoring, what you just added is a kludge. Sure, it’s a well tested, beautifully written kludge; but it’s still a kludge.

The trouble is, it’s easy to forgive yourself.

But it’s just a little if statement

It’s just one little change. In this specific case we want to do something subtly different. It may not look like it, but it’s a kludge. You’ve described the logic of the change but not the reason. You’ve described how the behaviour is different, but not why. Congratulations, you just grew a new hair.

An example

Perhaps an example would help right about now. Let’s imagine we work for an online retailer. When we fulfill an order, we take each item and attempt to ship it. For those that are out of stock, we add to a queue to ship as soon as we get new stock.

public class OrderItem {
    public void shipIt() {
        if (stockSystem.inStock(getItem()) > getQuantity()) {
        } else {

As happens with online retailers, we’re slowly taking over the universe: now we’re expanding into shipping digital items as well as physical stuff. This means that some orders will be for items that don’t need physical shipment. Each item knows whether it’s a digital product or a physical product; the rights management team have created an electronic shipment management system (email to you and me) – so all we need to do is make sure we don’t try and post digital items but email them instead. Well, the simplest thing that could possibly work is:

public class OrderItem {
    public void shipIt() {
        if (getItem().isDigitalDelivery()) {
            email.shipItem(getItem(), getCustomer());
        } else if (stockSystem.inStock(getItem()) >
                       getQuantity()) {
        } else {

After all, it’s just a little “if”, right?

This is all fine and dandy, until in UAT we realise that we’re showing delivery in 3 days for digital items. That’s not right, so we get a request to show immediate delivery for digital items. There’s a method on Item that calculates estimated delivery date:

public class Item {
    private static final int STANDARD_POST_DAYS = 3;
    public int getEstimatedDaysToDelivery() {
        if (stockSystem.inStock(this) > 0) {
            return STANDARD_POST_DAYS;
        } else {
            return stockSystem.getEstArrivalDays(this) +

Well, it’s easy enough – each item knows whether it’s for digital delivery or not, so we can just add another if:

public class Item {
    private static final int STANDARD_POST_DAYS = 3;
    public int getEstimatedDaysToDelivery() {
        if (isDigitalDelivery()) {
            return 0;
        } else if (stockSystem.inStock(this) > 0) {
            return STANDARD_POST_DAYS;
        } else {
            return stockSystem.getEstArrivalDays(getSKU()) +

After all, it’s just one more if, right? Where’s the harm? But little by little the code is getting hairier and hairier.

The trouble is you get lots of little related hairs smeared across the code. You get a hair here, another one over there. You know they’re related – they were done as part of the same set of changes. But will someone else looking at this code in 6 months time? What if we need to make a change so users can select electronic and/or physical delivery for items that support both? Now I need to find all the places that were affected by our original change and make more changes. But, they’re not grouped together, they’ve been spread all over. Sure, I can be methodical and find them. But maybe if I’d built it better in the first place it would be easier?

A better way

This all started with a little boolean flag – that was the first smell. Then we find ourselves checking the state of the flag and switching behaviour based on it. It’s almost like there was a new domain concept here of a delivery method. Say, instead I create a DeliveryMethod interface – so each Item can have a DeliveryMethod.

public interface DeliveryMethod {
    void shipItem(Item item, int quantity, Customer customer);
    int getEstimatedDaysToDelivery(Item item);

I then create two concrete implementations of this:

public class PostalDelivery implements DeliveryMethod {
    private static final int STANDARD_POST_DAYS = 3;
    public void shipItem(Item item, int quantity,
                         Customer customer) {
        if (stockSystem.inStock(item) > quantity) {
            warehouse.shipItem(item, quantity, customer);
        } else {
            warehouse.addQueuedItem(item, quantity, customer);
    public int getEstimatedDaysToDelivery(Item item) {
        if (stockSystem.inStock(item) > 0) {
            return STANDARD_POST_DAYS;
        } else {
            return stockSystem.getEstArrivalDays(item) +

public class DigitalDelivery implements DeliveryMethod {
    public void shipItem(Item item, int quantity,
                         Customer customer) {
        email.shipItem(item, customer);
    public int getEstimatedDaysToDelivery(Item item) {
        return 0;

Now all the logic about how different delivery methods work is local to the DeliveryMethod classes. This groups related changes together; if we later need to make a change to delivery rules we know exactly where they’ll be.


Ultimately writing clean code is all about discipline. TDD is a great discipline – it keeps you focused on the task at hand, only adding code that is needed right now; all the while ensuring you have near complete test coverage.

However, avoiding hairy code needs yet more discipline. We need to remember to describe the intention of our change, not just the implementation. Code is primarily to be read by humans so expressing the reason the code does what it does is much more important than expressing the logic. The tests only ensure your logic is correct, you also need to make sure your code reveals it’s reasoning.

Read Full Post »

Older Posts »

%d bloggers like this: