I started by writing a broad post about design, and it got away from me (apparently I should have spent some time designing the post first…), so I deleted it all and decided to write something shorter, and, with any luck, more understandable and useful.
I’ve been reading some discussions about how design relates to Agile. Some teams get into trouble because they think that agile means “no design”, when in fact it means “right design”.
The whole point of design in my mind is to save you work later on. There’s a sweet spot between no design and big design that makes sense in a particular situation. I don’t think that’s a unique insight at all, though I have seen groups how use the “design document” approach where there’s a document with 18 sections in it that everybody has to use.
The two areas I would like to talk about are about what you are building and the scope of what you are doing right now. I’ll talk about scope first.
The amount of design you should do depends on the scope of what you are doing, and scope in this situation doesn’t mean “amount of code change” (though it often correlates somewhat with that), it means “impact of code change on the customer”. This is obviously different for every change you make to the code, and my general guideline is that spending 5 minutes bouncing your thoughts off of somebody else generally gives you a good enough conclusion about how much design is required. Notice that I said “guideline” – I expect that developers can use their best judgement about when they can make changes without consulting with others.
Some people would say that not having the opportunity to make a wrong choice about when to consult with others is a strength of pair programming. I think that’s probably true, but obviously only works for teams that do pair, and that’s not that common in my neck of the woods (and, I suspect in others).
So, anyway, that’s what I think about scope, and, once again, I don’t think it’s a unique insight.
My second point – that the amount of design depends on what you are building – is something I haven’t heard talked about much, especially in agile circles. Because most software developers deliver applications, the agile processes are described in that context.
And in that context, I think that many developers do far too much design up front. You can spend 3 days writing something up that covers how you will do something, or you can spend 2 days doing early implementations and then know which one works better, and have real code to show people. Trying to figure out how things should work before you write them is often less efficient than just writing them when you need them.
Given that I consider premature generalization to be the #1 sin of developers, no surprises there.
But – and I think I may be finally getting to the point – that perspective comes from applications, where you own the code that you’re building, and refactorings can be done when you learn more.
Platforms are different.
If you are building a platform, things get a bit schizophrenic. Internally, you are an application – you can refactor the internals without a lot of impact elsewhere, and therefore the amount of design you do should keep that in mind.
But externally, people depend on your APIs to stay the same. This means that, for a given feature, you need to get it right (or as close to right as you can) on your first release. It also means that you need to think about how the feature that you’re doing right now might be extended for things you might do in the future.
Which is exactly the thing that you shouldn’t be doing if you’re building an app, because it’s a pain, it’s expensive, you’ll make the wrong choices, and you’ll have to throw work away.
In my current team, we own both applications and platform API, so we get to spend time in both of these areas.
And now it’s lunchtime. I may write a future post on how I think you should do platform design.