You suck at TDD #3 – On Design sensitivity and improvement


Through an above-average display of ineptness, I managed to overwrite my first version of this post with a response I wrote to the comments. Since I’m too lazy to try to reconstruct it, I’m going to go a different direction. In a recent talk about design, I told the attendees that I was going to insult them during the talk, and it worked pretty well, so I’m going to try the same thing here:

You don’t know how to do design. You would not know a good design if it came up and bit you.

To explain this, I feel it necessary to talk a bit about ignorance. I will loop back to the topic at hand sometime in the future.

In a really cool article written back in 2000, Phillip Armour wrote about 5 orders of ignorance, which I’ll summarize here:

  • Oth Order Ignorance (0OI) – Lack of ignorance, or in other words, knowledge. I have 0OI about skiing.
  • 1st Order Ignorance (1OI) – Known lack of knowledge. I have 1OI about how to knit, but I can think of a number of ways to convert this to 0OI.
  • 2nd order Ignorance (2OI) – Lack of awareness. I have 2OI when I don’t know that I don’t know something. I cannot – and this is the point – give examples here.
  • 3rd order Ignorance (3OI) – Lack of process. I have 3OI when I don’t know a suitably efficient way to find out that I don’t know that I don’t know something.
  • 4th order ignorance (4OI) – Meta ignorance. I don’t know about the 5 orders of ignorance.

 

Like any model, this is a simplification of what is really going on, but it’s a useful model.

Back to the insult, but this time I’ll reword it using the orders of ignorance:

You have 20I about design; the code that you are writing has obvious problems with it but you do not see them because you are 2OI about these problems and therefore cannot see the problems yourself.

It’s a little less catchy, and that’s why this series is named "You suck at TDD", not "Systemic influences and limitations in human knowledge acquisition have limited your effectiveness at TDD in interesting ways".

You can probably think back when you learned something about coding – for example, there was probably a time when you learned it was good not to repeat code. Before you learned that, you had 2OI ignorance about it, and now you no longer do.

We *all* have at least some 2OI about design; it’s just a feature of how knowledge acquisition works. That is not the real problem.

The real problem is that most developers have both 3OI and 4OI when it comes to design. They don’t understand how 2OI works and therefore think that they have good design skills, and – probably more importantly – they don’t have an efficient way of identifying specific instances of 2OI and converting them to 1OI and ultimately 0OI.

Or, to put it more concisely, most developers think they are good at design because they can’t see the problems in their designs, they don’t really understand that this is the case, and they don’t have any plan to improve.

If you couple this with our industry’s typical focus on features, features, features, it is no longer surprising that there is so much bad code out there; it becomes surprising that there is code that works at all.

So, tying this whole thing back to TDD, the reason that TDD does not work for a lot of people is that they don’t have sufficient design skills to see the feedback that TDD is giving to them. They get to the refactor step, shrug, and say, "looks good to me; let’s write the next test". And these 2OI issues add up, and they make it harder to do TDD on the code, and it gets hard to do.

This is not surprising. TDD is about evolutionary design, and if you aren’t very good at design, it’s not going to work very well.

Improving your design skills

The remainder of this series is about improving your design skills. I will probably focus on specific patterns that I find especially useful in the TDD world, but I’d like to provide some general advice here. These are things that will help you move from 2OI to 1OI in specific areas of design. And please, if you have other ideas, add them in the comments:

  1. Pair with somebody who cares about design. They will be 1OI or 0OI in areas where you are 2OI, and by having discussions you will learn together.
  2. Read and study. There is a *ton* of useful information out there. If you like abstract, read – and then re-read Fowler’s book on Refactoring. If you like more specificity, go read information about a single code smells, and then find it – and fix it – in your code. If you want a bigger example, just search for refactoring, and you’ll find examples like this.
  3. Share and teach. You may think that you know something about a specific area of design, but when you go to teach it to others, that is when you really learn it.
  4. Practice refactoring skills. If you are lucky enough to work in a language with good refactoring tools, train yourself to use them instead of hand-editing. Not only will this speed you up and reduce the errors you make, it will train you to think differently about code.
  5. Practice TDD and experiment with different approaches. What does "tell, don’t ask" do to your code? Can a more functional programming approach have benefits?
Comments (4)

  1. Ian says:

    I tried to encapsulate something along these lines in a blog ages ago, but with more rant. It was in response to a round of interviews I'd been conducting which initially made be despair at the quality of candidates available and then reflect to on my development over the years.

    There have been numerous points in my career where I've felt almost omnipotent, only to realise as my skill increased that really I just didn't know what I didn't yet know.

    I still have the same problem with candidates today. What I consider a senior developer vs what the candidates senior developers consider to be a senior developer varies significantly.

    Of course, I still don't know what I don't know, so I imagine my idea of what's important will be refined further, but I can't be paralysed into inaction and have to make a judgement call based on what I do know too.

    What I can do is acknowledge that this is a process developers go through and perhaps, if they manage not to really piss me off during the interview, I can open their eyes a little.

    If you want a visual analogy. You could imagine the path to developer perfection as being a ladder, with developers scattered along the length from top to bottom depending on their current ability. The problem is developers can only look down, so as they progress, their perspective is of being at the top of an ever lengthening ladder rather than advancing along the length of an already long one.

    This is why I didn't write the blog post in the first place, I can just about articulate the problem but couldn't find a solution to end on. Acknowledge what you don't know you don't know is an obvious but nebulous one but I wanted more.

  2. Mihai says:

    You could consider linking to sourcemaking.com for Code Smells and Refactoring.

    I've used it on a number of teams, and it helps with awareness.

  3. Pavel says:

    "Ignorance sucks!"

    Nice post Eric. In the practice refactoring skills/pair with someone section – I would suggest looking into code retreat format. I found it to be very efficient way to introduce people to new concepts (moving them to 1OI I guess) with hands on practice.

  4. Ultimate says:

    How do I know whether there is someone with 1OI or 0OI. I've 3OI about that information.

Skip to main content