I'm occasionally asked for advice on how to be a more productive programmer. My response frequently seems to disappoint, but it's the one I believe confers the greatest immediate results: Get a second monitor. The ability to have a Web browser in a window beside multiple open code windows is a huge productivity boost. Add windows for documents, all tiled so that everything is visible at once, and I have before me a vast visual plain of all the needed support items as I focus in on the one window where furious typing is being magically transformed into working, legible code.
But more than a simple hardware solution, people want to know about personal habits that have contributed to being productive. In the past, I've discussed some helpful practices: using mind maps for design, keeping an inventory of the small design decisions I make as I code, and so forth. So here I'd like to discuss several fundamental practices that I adopted by appreciating the repeated cost of not doing them. They are the practices of experience that I wish I'd understood earlier.
Know your principal tools thoroughly. I am still surprised to see how frequently developers know only a small subset of the commands and features their principal tools offer. Watching them do things manually that would have been trivial to do if they knew their editor, IDE, or build tool better is as agonizing as watching a clerk who can't type enter your name and address into an online form, one searched-for keypress at a time. You just want to say, "Spend the few hours necessary to learn the basics and you'll reap enormous rewards."
Keep up-to-date breadcrumbs. Every developer knows the personal cost of interruptions and unavoidable context switches. I find it much easier to deal with them, especially long interruptions, if I keep notes on what I was doing and where I thought I was going. Typically, the notes consist of what remains to be done before I can check in the code. It'll be something like:
- Verify new code doesn't hang when there is no connection
- Add Jeff's suggestion to the
- Unit tests for the data extraction
As you can see, it's nothing dramatic, but it allows me to return quickly to what I was doing. As I'm coding, I might insert an occasional tasks in the list. But it's important, I believe, to keep the list short and mostly trivial. Important things should go into the defect tracker. This is purely a set of reminders, so that I have less to recall later and can quickly return to what I was doing.
Test constantly while coding. Personally, I think the single most important contribution of the Agile movement to programming is communicating the value of developer testing (generally, unit testing). I am not an advocate of TDD and feel that many of the critiques directed at it are valid. But I am a passionate believer in unit testing. Of all the practices here, this is the one that would have served me best in my salad days. The ability to check in code knowing that it's unlikely to contain silly errors and overlooked conditions allows me to have a much clearer idea of what progress I've made. I don't have to worry nearly as much that there is still an extended debugging cycle of unknown length ahead of me. I now compile with the expectation the code will work the first time, rather than entertaining the fond hope that it might.
Fully automate the pipeline. This seems like unremarkable advice. But it got me to continuous delivery before that concept had a name. I automated build, test, deploy. I also automated updates to the website, to the Javadocs, to just about everything I could possibly update as part of the regular build. While this took a lot of time to write out (using Ant), the payoffs are continual. By having automated everything (well, except for some manual tests) I can build with high confidence in the generated software, even if a given feature is incomplete. I don't worry at all about fragility. In the future, I expect to automate things even more: I want to write more scripts that simulate all the possible installation options and make sure they all work correctly or provide accurate error messages. Right now, I'm pretty sure they do, but I don't know for certain because of the absence of this step from the automated pipeline.
There are certainly other practices I wish I'd learned a lot sooner. If these are helpful, then in the future, I'll present some others and invite other developers to share their words of wisdom. Till then!