Wednesday, November 22, 2006

Question-Driven Development

I wrote my first computer program when I was a freshman in high school sometime around 1970. Contrary to popular belief, I was not banging out code on clay tablets. But I was using punch cards. Even so, I was using a dedicated mini-computer, and just a couple of years later, transitioned to an interactive time-sharing system. I remember fondly a couple of years after that, trudging through hip deep snow, three miles, up hill, both ways, to the college computer center.

It took me more than thirty-five years of writing code to put a name to my personal software process: Question-Driven Development. I find that I am constantly asking questions about my code as it, more or less, magically appears on the screen in front of my eyes. Sometimes the question is what the hell is this? But just as frequently it is one of the following.

How will I test this during development?
  • Can I unit test every single code path?
  • Do I have error legs that are difficult to exercise?
  • Have I checked my code coverage using tools like Cobertura?
  • Do I have confidence that taking a rare error leg won't somehow escalate the problem?
  • Are there private inner classes that need to be tested independently?
  • Have I tested my settors and gettors?
  • Do I have reasonable defaults if the settors aren't used?
  • If settors must be used, why aren't those settings set during construction?
  • Can I have a no-argument constructor, and if not, why not?
  • Have I tested my component for memory leaks using tools like JProfiler?
  • Have I done static analysis using tooks like Klocwork?
  • Is this code thread-safe, and if not, why not?

How will I debug this during integration?

  • How can I tell if its a bug my component or another component?
  • Are the interfaces between components independently verifiable, and if not, why not?
  • Are there independent ways to indict my component versus other components?
  • Do I have a reasonable message logging framework?
  • Have I chosen the severity of each logged message appropriately?
How will I troubleshoot this during quality assurance?

  • Can I quickly indict the failing subsystem?
  • Will turning up the log level while under load firehose the screen or the log file?
  • Will turning up the log level while under load somehow escalate the problem?
  • If performance problems arise, can I determine where the time/space is being spent?
  • Do I have a way of independently testing my component in the context of the larger system?
  • Do I have a way of testing my component end-to-end with the other components?
How will I support this during customer deployment?

  • Can I indict our software versus other software?
  • Can I efficiently capture the forensic information I need in a transportable form?
  • Can I quickly get the customer's system back up and running?
  • What is my priority when a problem occurs: forensic data capture or returning to an operational system?
  • Can I quickly determine a plausible story to reassure the customer?
  • Is that story likely to be correct or am I going to look stupid later?
  • Are development resources available to quickly fix bugs and turnaround a new release?
  • Have I given the field support folks the tools they need to get their job done?
  • Can the field support folks do their jobs without calling me all the time at all hours?
  • Have I chosen the severity of each of my external alarms appropriately?
  • What is the cost of raising an alarm?
  • Can the system recover automatically or are there circumstances where our field support folks need to roll a truck?

How will I transition this to another developer during my move to another project?

  • Will the new developer need to be a subject matter expert like me?
  • Do I need paper documentation or is a wiki or javadoc more appropriate?
  • Have I left the new developer a mess to clean up?
  • Do I have deprecated code that I need to remove?
  • How do I know for sure that no one is using the deprecated code?
  • Is the deprecated code unit tested?

What other questions should I be asking?


Demian L. Neidetcher said...

I like the approach.

Here are some of the questions I ask myself as I'm writing code. They're more low level than what Chip has.
- Will this make sense to me 2 projects from now?
- Do I have self documenting code and naming?
- Am I being cute? If so, do I have a good reason?
- Is there a simpler way to do this?
- Am I calling things by the same name; verbs and nouns?
- Is someone else on this project doing things a certain way, should I be doing it that way?

Chip Overclock said...

I like these questions. So to my list I would add: Am I conforming to the predominant coding style of those who came before me on this project, and if not, why not? Am I using a consistent naming style so that other developers might make reasonable guesses as to method, class, and variable names? Am I being unnecessarily clever? I once had the experience of having a junior programmer bring a code listing into my desk to ask for some help in modifying it. It was in IBM 370 assembler. It had my name on it, and a date ten years earlier. Maybe I was having a senior moment, but I had absolutely zero memory of the project. Not just the file, or the module, but the entire project. No fracken' clue. Really. Apparently I had written a bunch of IBM 370 assembler for this project, and has expunged it completely from my memory. Thank Ghod for good comments. Between the two of us, we were able to figure it out.

Anonymous said...

My first reaction was to agree, but then I correctly parsed the title.
I do question driven developments.
While developing, it is important to step back and review whether you are developing the right thing.

I think your list is excellent for thinking about the coding. As noted in the previous paragraph I would add:

Does this component do what the customer wants and needs ?
Would some functions be better parsed into different components ?
Do this component and the others with which it interacts have a clear
and common understanding of what is being done by which, and how that is communicated ?

Have you considered: how would I support this code if I had never seen it before ?


Anonymous said...

Lots of very good programming things to think about. But...

Maybe I read this too fast, as I didn't see anything regarding the goal or setting. For the above I'd say it was "You are given more time than you have ever been given in your career to write some code you expect to have a long life cycle."

Gee, wouldn't that be nice.

In general, it is, "You have one week to write the ??? driver, after that you have another week to make it meet the performance expectations. We need this done fast so we can meet our market window. BTW, we promised this to a customer next month."

The reality of TIME plays a big role in how much programming ART you can put into a project. Maybe I suck at what I do, but I can't think of a project I've done where I didn't have a comment like "is this the right place for this?" or "Hack - blah blah".

So like all things a balance must be struck and priorities are set. What questions are of the highest priority? Don't answer, it depends on too many other dimensions.