June 11, 2009
Undermining the Design Process: Thinking Outside the Black Box
by rz
I've been accused of undermining the design process. And yes, I do. Here's why.
Reason 1: I operate in an environment where most of the design choices have been made for me already. They have been made in sensible ways -- probably better than if me and my team would go and make them.
In Code Complete, McConnell goes in great depth into how spending time up-front designing the architecture, the sub-systems, and the components of each sub-system of a software project pays off handsomely because it costs less to change a design or design document than to re-write a chunk (or all) of the project. Well duh.
If I were writing the avionics system for an A330 or the first version of an accounting software package for a large corporation I'd probably be inclined to have the whole thing fully specified before writing any code. The design process would be a very significant chunk of work. The team would likely be faced with a lot of choices for components, we'd have to make sure that all the components won't fail in some catastrophic way, we'd need to know what kinds of user interfaces to expect, etc, etc. And then yes, in that case McConnell is right and I agree with him fully and I'd be using the checklists and guidelines in Code Complete.
But I don't do that.
I write web applications. That severely restricts the problem space. Sure, I could be at the forefront paradigm-shifting and cutting the edge of web application technology (or what's worse I could've been writing web apps in the 90s). And then I'd be re-thinking the way we go about it. But I'm usually not. Most (all?) of the time it is a SQL db with urls, views and templates, and an admin interface on top. There may be some other data processing untied to the web-requests, but the ORMs work there, too. And then Django (or Rails, or webpy, or...) does the trick. End of story. The very-talented lot of Django developers have already made a lot of crucial design decisions for me. And it works.
As far as web applications go, right now we're late in the technology wave. Which, again as per Code Complete, reduces the amount of work that needs to go into design.
Writing mobile applications is equally constrained. And so is writing software on top of existing services (e.g. on top of the twitter or facebook APIs).
Reason 2: getting something coded up quickly may have costs later on when I have to re-write, but it also has benefits.
You can't get users on your design documents or your blackboard diagrams. But you can on a site with a poorly designed backend. Rewrite later. The users will provide a much better idea than the design documents about what the problems are.
An investor is probably more impressed by a live site that works and has users than by a very complete specification of the software you are going to write.
It is hard to talk to the client with "this will happen like that" statements. Much easier to say "take a look, is that close to correct? what needs to change?"
Of course, it is the nature of distributing software on the web that allows this. If I were shipping products shrink-wrapped this wouldn't be so. Like I said earlier, the fact that I write web applications takes care of a lot of the design process.
The best specification for the database schema is the app's models.py. You get a design document and a chunk of code written. Oh it is wrong? python manage.py reset_db (requires the django extensions :-).
I'm not advocating going from 0 to code here. No. Having a Jason Fried style functional spec is a bare necessity. But keep it minimal. Keep things as close to their final form as possible. Keep things real. Sorry for the bad reference. I just reminded myself of Pierre.
Reason 3: software is always written in a broader context.
People tend to talk or write about software design as if it happened inside a black box, for its own sake, without any other moving parts. And yes, if you are in charge of designing infrastructure for the next google data center maybe you get to operate that way. Best practices everywhere. You can take your time to plan. Groovy.
In more mundane cases everything is a tradeoff. Including time spent designing. Sure, now that you've designed your app properly it will be a breeze to scale it. But maybe you won't get to the point where you need to scale it because you spent too much time designing it.
I think this is the same reason DHH counts on Moore's law to keep him from sharding: lazy evaluation. The design process is a form of strict (anti-lazy) evaluation. It is trying to mitigate risks by virtue of foresight. I suck at foresight. So I'm fundamentally lazy.



