The Myth of the Detailed Design Advantage
There's a lot of approaches to the concept of software design, as it relates to software delivery. The places I've worked have spanned the spectrum from detailed up-front design to mostly agile approaches where very little design is done.
What I find odd and, frankly, erroneous is the idea that doing a large amount of detailed design work up front will:
- Make delivery faster
- Minimize unknowns
- Offer more precise delivery estimates
- ???
It seems that way because most of the questions get answered during the design phase. It probably is true that a detailed design gives you #2 and #3, and perhaps other things (#4). Importantly, however, it does not make delivery any faster.
Again: Detailed designs will not help you deliver any quicker.
There's a time period between concept and delivery. This time period is more or less constant:
|------------------------------------------------------------------|
There are some things you can do to make this time shorter: Add resources, or hire smarter people, for example. And there's some things you can do that don't really have any effect on the time period, like design work.
|-design-----------------------------------------|-implement-------|
For example, this graph indicates a lot of up-front design work.
|-design-----|-implement-------------------------------------------|
This graph indicates a more agile approach, with very little design work up front.
If you do the design work up front, the implementation becomes quicker and more predictable because you answered more questions during the lengthy design phase. If you go agile and do very little designing (mostly just story cards), implementation is much more exploratory and less predictable as a result. Mostly, though, you end up exerting the same amount of effort to get a delivered result.
Another thing these graphs can tell you is how happy your developers are:
|-design----------------------------------------------|-implement--|
These developers hate themselves and are looking for work elsewhere.
|-design--|-implement----------------------------------------------|
These developers love their job so much their faces hurt from smiling so much.
Clearly, if you want happy developers you should quit making them write such detailed design documents. The whole time they are writing those design documents, they wonder why they aren't just writing the code anyway. And you aren't really gaining anything by having them do such a laborious quantity of design; your delivery date will be the same anyway, so you might as well let them get to work.
Of course, there might be one small problem. You're clearly convinced, now, having read my very persuasive argument. But your project manager, or your boss, or the company policy-maker, might have a personal rule about reading my blog and they insist that they must — MUST!!! — have a much more predictable and trustworthy measurement, and they can't do such a small amount of design and leave the implementation so wide open and crazy.
If that is the case, it is time to relabel some things. Do a lot of up-front "design," where "design" means "mostly prototype, and also do some design." Now your graph looks like this:
|-mostly prototype and also design--|-implement--------------------|
This should make everyone a bit happier.
Hard Coded Breakpoints
This little line of code totally saved me this week:
__asm int 3;
I'm writing a plugin to an existing Windows application and I could not, for the life of me, figure out if my plugin was even being loaded or if it was executing properly. All I knew was that I wasn't seeing the behavior from my plugin I expected. I needed to step through my plugin with a debugger, but since it loads as part of another app I didn't know how to get the debugger to break. Setting breakpoints in Visual Studio wasn't working.
Fortunately for me I have smart teammates, and one of them taught me this little trick to programmatically insert a hard coded breakpoint into your code. If I add this line, when my code runs the breakpoint is triggered and the application stops executing, with a dialog giving me the option to debug it in Visual Studio. When I get in there, behold: The cursor is pointing at that line of code and I can step through my plugin.
Since then I've done a bit more research and found out that, in truth,
__asm int 3;
is really only meant for x86 architectures. A more portable way to do this for Windows is:
__debugbreak();
which invokes the correct assembly interrupt for the current architecture.
On Linux, apparently you can do this:
__asm__("int $0x03");
although I haven't tried it. It looks enough like the x86-only version for Windows that it makes me wonder if it would work on x64 architectures; I'd love to hear back if anyone knows for sure.
Also, interested to know how to do this on OS X. Comment or mail if you know.
