Monday, October 02, 2006

Writing code or writing specs?

The eternal dilemma; anyone who's ever written software faces this dilemma all the time, that is,

Do you write down (on paper) what you (or someone else) are going to do and how it will work or do you just write it (in code)?

There are tons of development methologies, approaches, styles out there in groovy world of software development, but none I have ever read or used is very clear about this important point, to spec or not to spec, that is the question. To be honest I don't subscribe to any formal approach, I tend to use my experience and "gut" to guide me these days, however one thing is for sure, I try not to do too much of either. I find that if I write too much specification then I end up taking too long and get things wrong (aka analysis paralysis), its hard to get the big picture from a 1000 pages of spec. Also if I write down every microscopic detail of how I want something to work then what's left for someone else to do, IMO creativity in software development is an important part of enjoying it. If I don't write enough specification then I end up taking too long often with an experimental mess that's expensive to maintain at the end of it. Detail is needed to explain the why and the how, especially when it's not the designer themselves writing the code.

Well, my latest masterpiece has reached that point (again), the point where I think I have written enough spec. to start writing some code, the approach I take is to write specific and targeted fragments of code (usually the hardest or the least clear parts of the design) This process is always time consuming because its difficult to write something that actually works to the point of being useful, without a lot of supporting stuff around it; so quite often I end up spending more time writing things to create data and meta-data so that I can actually write and test the thing I wanted to in the first place. However expensive though, I find this a critical process; I often *need* to write code in order to establish how I'm going to design something, there is just no other way (without unlimited time that is) Having written code to the point where I am clear in my thinking (this usually involves showing other people!) I will often then revert back to the specification and change and/or complete it.

A trendy word for this process is "prototyping" or iterative development (sometimes called RAD) On the surface it seems like an obvious way to tackle complexity, however a lot of "day-coders" I have known never really "got" the point of the prototype, they mostly thought it was a waste of time, why prototype surely you are clever enough to get the spec right first time? well, no, actually I'm not, neither were they. In my view the point of a prototype is to prove a design feature (either logical or physical), nothing more, nothing less. It is however skill based, i.e. you have to know what you are doing to use it successfully; in my time as a programmer and manager I've seen some hideous products emerge from aimless prototypes or more commonly, chronically disfunctional components that emerge from hopelessly simplistic screen "mock-ups" that were supposed to tell the coders what a system is logically supposed to do. Prototyping and iterative development are things that unfortunately have a bad rep in some quarters, usually because of good old fashioned arrogance (we don't need no stinking prototypes), done right though I believe it's the best approach.

Although powerful, I find this iterative approach requires a lot of discipline; the desire is often strong to simply push on with the code and forget about the spec altogether; this is usually a bad thing in my experience. It's good to write down your design; often it's not until you do this that you see the holes (at least before a coded version is complete, by which time it's too late!), in any case, you should be able to write it down, if you can't then something is wrong. The other good thing about doing things this way is that you actually end up with something that you can show other people; it's often hard to articulate what something will do to either technical or non-technical colleagues, the prototype is a vehicle to do that, but beware, make sure it doesn't become the rod that these same people beat you with when V1 is completed.

My "golden rules" of prototyping

1. A prototype should have some specific "point"; otherwise its just an excuse to cut code too early; a prototype of the *whole* system is pointless

2. Prototype logical or physical things, what or how, don't confuse the two, make sure you know what it is you are testing and that you capture the answer (ideally back in the design documentation)

3. Prototypes are not a substitute for design docs (specs) - unless the prototype is so broad and deep that the spec is not needed (rare, see point one)

4. Prototypes are not excuses for not testing things properly; just because your design held water with 5 transactions doesn't mean it works for 5 million.

5. Sometimes prototyping is harder than just cutting code, clearly if you always get things right first time then you don't need to bother.

6. Make sure the people you show your prototypes to understand what they are looking at and what you expect them to do/say - prototype is not equal to a finished product minus some smoothing of rough edges.

7. Prototypes must have secretive and alluring code-names; dagger, bart, helix, google etc.

No comments: