Thoughts on agile design and platforms
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.
I think it’s important to note that Agile isn’t about no design (as you say) but it’s also not about no big design. At the lowest level, Agile is about recognizing that requirements change through the life of the project and that Agile is about performing the design in response to change. What "design" means (in terms of work-product) needs to be entirely up to the customer.
So, Agile is against "big design up front" because that’s counter to the realization that you can’t know what the entire design is going to be, since there will be change throughout the project.
While many projects fulfil this in a way; they fail to truly be Agile because they aren’t soliciting the customer for information to cause change. Just because you don’t do a big design up front and you do iterative design; if you’re not involving the customer in each iteration of the design, you’re not welcoming change. i.e. if you had all the same requirements when you finish design of your last iteration as you did when you started the project, you’re essentially doing “big design up front”. Thus, you’re missing the "Customer Collaboration" of Agile.
I disagree with your opinion that frameworks are different. A released application likely cannot change anywhere a developer feels like; a change needs to be vetted by the customer–much the same as an API. An application’s UI may also have the requirement that it can only be added to and no existing functionality can change. Many frameworks can change–if part of the API is simply broken, it can be removed or changed. There’s different "normal" degrees to which applications can accept change to their UI and frameworks can accept change to their API, for sure; but that doesn’t really mean Agile is different for Applications and Frameworks. It really means Agile is the same: you’re listening to your customer and doing what they ask.
Hi Eric,
great to hear that statement. We’ve been discussing this internally many times as my team is doing framework development whereas all others are effectively doing application development which indeed is totally different.
In a framework you mostly can’t do any changes to the API like "today it’s String.SubString(int start, int length) but we’d like to change it to String.SubString(int start, int end)" – even on a larger scale like renaming methods, types etc. as all of your customers will yell at you. And I’m not talking about doing bigger refactorings like changing the general way of how things work to completely change a design…
So I totally agree and I’m looking forward to your next posts!
Ooh
Good post. I think your distinction between designing framework APIs versus wholly-owned application code is important. Not sure what Peter Ritchie is trying to get at by disagreeing; the differences between API and application design are so large that I’m inclined to say that anyone who disagrees has never designed an API that got released into the wild and made it to v2.
One of the few .NET books worth having as a physical book, IMO, is the "Framework Design Guidelines" by Cwalina, Abrams, et al. As good as it is, though, it’s very much tuned to fx level (and is very frank about that; note the title). I’ve had several discussion with devs who’ve read that and think it’s scripture for app design. Most recently, I had someone tell me that we shouldn’t use underscores or case-sensitivity as part our C# naming conventions for nonpublic members, because the book cautions against language specific names b/c there are .NET languages that are case-insensitive or that may not have the same support for underscores. Of course, this guy also thought FxCop was the universal standard, too. I asked him why they didn’t just name it FxPope and remove the ability to turn rules off. I’m glad not to work there anymore…