Procrastinate Whenever Possible
8 May 2008 –Wil Shipley has a lot of wisdom in the arena of software development. And he regularly backs up his advice with results that prove him right. There is one particular theme of his, however, that really sticks with me:
START WITH BREVITY. Increase the other dimensions AS REQUIRED BY TESTING.
He actually takes his time to elaborate on the justifications and implications of this advice, culminating in an oft-linked-to post that is really worth reading. The first time I read it I thought it sounded nice, but it didn't quite *click*. It took about 6 more months of fumbling through base classes that I haven't implemented and interfaces that only get used in one place before I punted.
When you are handed a problem, if your first thought is "I will need a base class that does x and probably an interface for y" you are creating extra work for yourself. Writing abstract classes first is, very literally, solving problems that don't exist. When you're writing code, you don't have a problem until you are calling a method that doesn't exist, or doesn't do what you need. No programmer, no matter how good, can accurately predict what calls he will be making from hypothetical classes before they are written. Even if you have a complete class diagram for your entire application (and if you do, why didn't you spend that time writing the code?), it will be wrong. You will have to make changes as your ideas break on the rocky reality of implementation.
Many programmers, when they create a new class, add a ton of features to that class to make it "complete" -- that is, they try to anticipate everyone who may ever use this class, and they add methods that those hypothetical users may want...you may be saying to yourself, "What's wrong with flexibility?" Strangely, I was about to tell you. The problem is YOU ARE NOT A LIBRARY PROGRAMMER.

What Would Wil Do? "Start with brevity." Break the tasks into easily defined units of functionality, and take the first item off the list and code it concretely. Only build what you need to make that functionality work. After you encounter code that can be shared, write your base class. After you hit a problem that can only be solved with an interface, stub it out.
If you just wrote public abstract and you don't already have a class written that will be inheriting from it, stop right there. Backspace over that abstract keyword and start building your concrete implementation first. Put off best practice 'till tomorrow for what you can get working today. I guarantee you will have a more stable, maintainable product in the longest run, and you'll ship sooner.
This all is not to say that you should not have good design to your software. A good architecture is invaluable and irreplaceable. In a later post, I'll elaborate on design approaches that can be built in as your code takes shape, without burning time creating a base library instead of getting things done.
Content available under a Creative Commons license.
Site code and design may not be reproduced.

