I've had the idea for this project rolling around in my head for way too long. I've started to work on the design and get some things down on paper. But what kinds of things? What's the goal?
A Few Weeks of Programming Will Save a Few Hours of Design
Many software developers -- some emboldened by ideas like "being a 10x engineer", "hacker culture", and "being Agile" -- feel that the best course of action is to dive right in. (Whether or not "Agile" really means what they think it means isn't important to my point.) They start coding early, create some prototypes, and refine on the code and the interface. Maybe they use a tool like Rails to help scaffold a website that defines (or becomes) the interaction. There are a good number of very famous applications that exist, in large part, because they embraced these ideas.
If that works for you, great. But, I've come to embrace a different philosophy (which has only been grown further in my current job). Software should be designed. Every minute detail doesn't need to be spelled out in advance and the deliverables and milestones should be fairly lean and cumulative, but, nonetheless, software should be designed. Iterating on a design takes far less time than scrapping large chunks of code and, if done well, it means a better all-round product.
Experience, Interaction, Interface
At the heart of any piece of software lies the experience you want to convey to the user. What is it the user gets out of it? Why would they love using the software? At work, a client asked for us to integrate a system we had built into another system. And we did. With a few clicks and some keystrokes, you could import things into the new system. Now that it's built and in the wild, it really doesn't get much use. And the reason it doesn't get much use is that the other system is terrible. It's slow, it's unwieldy, and the users hate it. They aren't interested in integrating anything into it because they don't want to use it to begin with. But, the company is forcing them into it. So, they do the minimum amount of work possible and our system, although easy to use, doesn't help them do less work. And, even in doing that minimum amount of work with the other system, they were spending at least 2 hours a day at it. 2 hours a day not doing the work they signed up for. 2 hours a day feeling miserable. We discovered they put off using the other system until 2 hours before they left for the day.
Our problem wasn't the interface. It wasn't eggregiously difficult or slow to use and things are well labeled. Users understood what our system could accomplish for them. And our problem wasn't the interaction with the system. We made that as painless as possible. The problem was experience. There was nothing to love about what we were doing. So, we iterated on the idea a bit and worked through it from an experience angle. And we came up with our initial experience we wanted the user to have. We wanted them to feel like they got their time back when they used our system. We wanted them to feel more productive when they used our system. We wanted them to feel empowered when they used our system. So, we needed was to build a series of applications that helped them do just that. Small iPhone apps that helped them accomplish the normal tasks they performed. A web application for people sitting at a desk they helped organize their workflows. Simple, short interactions that gave us enough information to feed their loathesome "enterprise" system on their behalf.
You Can't Code What You Can't Explain
Beyond trying to understand why people will want what you build and then what to build, you've got to have an understanding on how it wil work. Design helps you uncover little idiosyncracies in your thought process. You may be thinking about keeping a cache of some information for easy retrieval. And that sounds easy, it's just some memory. But, really, you need to understand how you're going to invalidate the cache and how you're going to keep it consistent with its underlying data source. If you don't know how those things are going to work, if you don't understand how the application utilizes the cache and how your data moves through the system, you're not going to develop a very good caching mechanism. You're going to most likely build something that just eats memory for no good reason.
Or maybe there's something more technical that needs fleshing out. If you don't have an understanding for how, say, sockets work, you're going to have a difficult time creating something that uses them effectively. But, lets say you think you've got a good understanding of how sockets work and how your network communication needs to happen. So, you draw a little state diagram and write out some notes. Maybe later on, you learn that just because you plopped an array of bytes on a send() call doesn't guarantee that those bytes are sent (because it returns the number of bytes out of your array that it sent). Looking back at your design, armed with new knowledge, you can figure a way out of this mess. Looking back at the code, on the otherhand, may cause you to make a mistake because the code doesn't have a application need defined in it nor does it explain why you went into a particular state at a particular time or what some random variable means. And so one mistake compounds another.
This work needs to be done and it needs to be done at multiple levels of the application.
Goals and Progress
The point of all of this is to force thought on what to build, why, and then how to build it. You do this until it becomes so clear and simple that you can explain it to someone else without there being any confusion.
For where I'm at in this design, I'm still on experience and interaction and . I haven't even begun to talk buttons and colors and logos and fonts and apps vs. websites. I'm still refining the idea. I'm also focused on system and large component levels of the architecture. I'm cheating a little by hopping between this and the experience idea, but both are fairly foundational things. I have a good enough idea of what the app is going to need at a base-level architecture that I can start to make some progress there. The really important thing is that I don't run off and build anything beyond a very high-level architecture without nailing down the rest of the app and how the releases will get scheduled.