Editor's Note: I originally wrote this for Fuel Your Coding back in October of 2010. Unfortunately, that site is now defunct, so I'm republishing the article here for posterity's sake1. I considered updating it for modern times, but I think it holds up well enough as is. Enjoy.
Today’s software development culture promotes rapid development methodologies, minimum viable products, releasing early & often, and the axiom that "real artists ship". What common thread weaves its way through all of these things?
If you haven’t felt the pressure to squeeze one more feature in before the release date, to fix an interface bug “RIGHT NOW!”, to get your product launched before your competition, or to shave a week off of your development schedule then you haven’t been developing software for all that long.
What many people fail to realize — and what I’ll emphasize in this post — is that the compromises we often make when optimizing for development speed can actually slow us down. More succinctly:
If you want to move faster, you have to slow down.
Allow me to demonstrate this concept in a few key areas of software development.
Automated tests are one of the first things to get tossed out when on a time crunch. Writing tests takes time, and that time could be spent implementing features. The problem with this line of thought is that one way or another the software needs to be tested before it’s released, and the less you automate the more you end up testing manually (how many times have you stepped through the same web form to test server responses?).
The added benefit of writing tests alongside your implementation code (preferably before it) is that it forces you to think about the problem space and you go into your implementation having put much more thought into it. So yes, you spend time writing tests, but you make it up in reduced implementation time.
The Big Win™ with building up a solid test suite is it reduces the amount of work you have to perform later when you refactor or add new features, making it a HUGE time savings as the system becomes more complex. Regressions suck. A solid test suite helps avoid them.
It’s been said that there are only two hard problems in Computer Science: cache invalidation, naming things and off-by-one errors.
When it comes to naming things people often mail it in because it is hard and they think they are wasting a lot of time doing it. This “speed optimization” can manifest itself in variables named
tmp3. Those are ridiculous names, but even “okay” names that don’t properly describe what they represent can be quite troublesome.
Why is it so important to name things well and how could dedicating time towards that effort speed up development? Remember, code is written once and read many times. The ability for you (or more often, somebody else) to return to your software and pick up the context quickly is paramount in maintaining development speed. Nothing makes picking up context more difficult — and therefore time consuming — than non-semantic (devoid of meaning) variable, function, and/or class names.
Do yourself a favor: slow down and put some thought into naming things. Future-you will reap the benefits.
When time is of the essence documentation is often pushed to last or thrown out altogether. The problem with this is that it also impacts how quickly new developers (including yourself 6-12 months later) can come up to speed and be efficient. There is no better time to document your code than after you have just finished writing it. At that point it is still fresh on your mind and you know all the little gotchas that will cost hours & days of development time if the next programmer doesn’t see them coming.
One reason people think documentation slows them down is that they formalize it too much or end up writing novels about their software. If your code needs a novel to explain it, it is too complicated and needs to be refactored into smaller, simpler pieces.
How can you document code and keep up the speed of development? Follow these guidelines and you’ll find that adding documentation as you go (which is far less daunting than going back and documenting everything at the end) adds trivial amounts of time to the overall development.
- Put a brief summary at the top of multi-line functions
- Include inline warnings or explanations for tricky bits of code
- Always document the intent instead of implementation;2
- Make exceptions to these guidelines when it is prudent
The importance of documentation (as well as the form of it) varies from project-to-project, but almost all code needs these little breadcrumbs to be easily maintained & extended.
That’s just a handful of examples. I could go on to talk about code style & establishing conventions, optimizing for readability, habitual refactoring, and other such concepts, but it is the overriding principle that is most important:
Invest time to think about what you’re trying to accomplish and the best way to proceed from the start when your software is simple. That way when complexity rears its ugly head your development won’t come to a screeching halt.
Need to develop something quickly? Just remember that sometimes you have to slow down to go faster.