White PapersMore >>
- Architecting Private and Hybrid Cloud Solutions: Best Practices Revealed
- Defense Against the Dark Arts
This past weekend, I went on a one-man coding sprint. I spent 15 hours hacking away on my favorite open-source project. In part, I was driven by the recognition that giving an hour or two here and there to the project made it impossible to do much more than attend to details, minor issues, housekeeping, and documentation (all of which are valuable but don't move the product forward in the necessary ways). As I am currently blocked by the need to rewrite parser code, there was no way to get this done without putting aside several big blocks of undisturbed time. Hence, my one-man hackathon.
Because I wanted to gain the maximum benefit from the effort, I carefully laid out things ahead of time. This mise en place consisted of creating a wiki page, selecting and opening the tasks from the JIRA defect/task tracker instance hosted at Atlassian, and going over the changes I intended to make. Then, as part of the final preparations, I generated a batch of project metrics so that I could compare before and after stats. As I sat down to begin working in the first hours of the sprint, I did something else that I've been meaning to do for a while on an extended coding run: I opened a spreadsheet in Google Docs to record the design decisions I made as I coded.
I've done this exercise before, but not over as long a stretch as this. Each time I had to pause and decide which of two paths to take in the design of the implementation, I made a descriptive entry in the spreadsheet to record my choice. Now, as I look over the final list, I've become convinced that noting the many small design decisions I made is a uniquely valuable discipline. For the 15 hours of coding, I noted a total of 8 decisions. In past iterations, I used to write down lower level micro-design issues. This time, however, I captured only the ones that were likely to have an effect beyond this coding session.
With the benefit of hindsight, I can assess the notes and determine their value. The most evident benefit is that I can add the notes to the documentation (both user and technical), especially about decisions that impose small limitations. For example, while working on the handling of block comments in the input, I realized that I relied on the fact that the closing symbol for a block comment could not occur inside a line comment. There was a point where I had to decide to whether to parse line comments for end-of-block comment symbols. I decided not to. I noted this small decision. (For bonus points, do you know for certain whether the line comment or the end-of-block comment has primacy in your principal language? Most developers I ask guess on the basis of what makes the most sense to them. They actually don't know.)
My documentation now states clearly how we handle overlapping line and block comments, because I captured this note. I probably won't put this in the user docs (really, what are the odds this will hang up a user?), but I will definitely put it in the developer docs. Moreover, I've tagged the comment with the words "block comment" and "line comment," so that in the future, I can gather up all minor decisions on these topics should it become necessary to revise how we do things. Such a set of bread crumbs is not always necessary in straight-ahead code, but in parsers, it can make all the difference in the world.
As I captured these decisions, I started wanting to elaborate them with small explanations. These extra comments frequently referred to constraints in other parts of the code that made x, y, or z difficult to do or unnecessary. These notes will also be super helpful when I jump into this code in the future.
A small part of me suspects that some of my notes arose from decisions I should have foreseen before coding had I spent more time on design. It's hard to tell this early. And ever since "big design up front" has fallen out of favor, the world seems to move increasingly to depending on developers to make these small decisions based on their domain knowledge, familiarity with requirements, and awareness of the design/architecture.
As I do this more now that I'm convinced of its value I expect correlation between design and the mini-decisions made in the heat of battle will become salient. When it does, I'll report on it in this column or in a blog post.
Before signing off, I should note that the idea to do this is not mine. Like many good practices, its inspiration was Kent Beck. In a keynote at the late Enterprise Software Development Conference in 2010, he suggested this practice in passing. His larger point was that by writing down these decisions, we'd quickly become aware of how very many design choices are made while coding. He was right. When I first tried this exercise, I scribbled lots of small things of no particular importance. After a while, I got the hang of writing down only decisions that had the potential of effects outside the immediate code I was writing. And from there, I was able to secure the benefits I've been discussing. I hope you'll find them useful, too.