Here is something I struggle with: given a vague goal, how do you move towards reaching it, towards shaping something concrete out of it?
This is important, because all projects start with a big blob of vagueness. Folks who create the most concreteness out of that are the ones who have the biggest impact. I’m learning how to approach this, but I still feel like a non-swimmer in the shallow end with lifesavers. I’ve learned a little, by personal experience, and by observation.
The design space is huge and completely unconstrained at this point. There are too many unknown unknowns. How does one proceed?
First of all, formulate principles that will guide the solution. This is not design yet. These are high-level ideas that put constraints on the design space. For example, GMail chose the principle that search should be the primary email navigation mechanism. Think long and hard about these, because these principles will be baked into your code and your system in a way that can’t be “refactored” away later. This is where wizards (i.e. very senior battle-hardened engineers) can help. Often, choosing these is a matter of taste and design and conceptual integrity. It might sound wishy-washy but it’s hard. Document these well. This is your manifesto.
Once you’ve got a spine, you’ve got to add a few more bones.
The next step is to find one concrete idea, and build on it. This usually takes the form of a prototype, or a walking skeleton. It might have huge swaths of functionality missing. It might have serious shortcomings. It might be ugly. It might be slow. But that’s OK. Think of this as the spec of sand around which a pearl is formed. What is important is that it be concrete, and growable.
It needs to be concrete and tangible. Something you can show and demo and people can play with and talk about and criticize get excited about. People rarely get excited about design documents. They frequently get excited about working prototypes, even when they come with massive this-will-break-on-you disclaimers.
The other crucial thing is that it should be growable. Your prototype should not be a dead end. You should be able to put work into it and make it incrementally better. Adding something new or changing it should not require you to build a new one from scratch. In other words, it should support iteration. There may come a point when you have to throw one (or more away), but ideally that happens only when the prototype has brought you to a major insight that invalidates some of your basic assumptions. Even then, it would have served its purpose. And even then, you need something that will get you to that point quickly.
Which brings me to my most important point: iteration. Speed of iteration almost always beats quality of iteration. In other words, focus on learning and fixing, continuously and quickly. Don’t sweat too much about getting it right. Chances are, your idea of right won’t be the right one. Chances are that most other peoples’ idea of right won’t be either. Only by having something real to criticize and learn from will everyone figure out what right is.
Build, fail, fix—and repeat.