Whether it's building software, a business, or some other project, chances are you'll almost never get it right the first time. Years ago, I heard a story of a pottery teacher that tried an experiment on the class to find out the best way to teach pottery to the students.
A high school pottery teacher was addressing the class, regarding their new assignment. The teacher told half of the class that they had the semester to create their best pot, which they would submit to be graded. To the other half of the class, the teacher said they would have to make 50 pots and that they would be graded on their best pot.
Who do you think produced the best pot? If you said the second half of the class, you'd be correct. I think the story applies well to the art of software development and I don't mean just building 50 of something. So lets explore this a little bit, why did they do better?
Practice
This is the classical answer, and it has a lot to do with the way the mind works. Practice strengthens the neural pathway in the brain. When you first learn something, it requires a very conscious effort. But as you practice, you become more efficient until you can perform the task almost without thinking. Regardless of whether you're doing pottery or writing software, this not only makes you faster, but when you can do these things "without thinking," you can spend more time thinking about other things. In other words, it will free up your mind so you can focus on the finer details.
Blinded by Perfection
The first group were too busy trying to decide what makes the perfect pot, and they are never able to make it because they don't have the necessary skill to achieve their goal. However, the second half of the class was forced to make pot after pot and refine their process.
In software, this is commonly referred to as analysis paralysis. Where you spend so long trying to figure out everything, you never get around to actually starting or finishing. However, when you're forced to spend more time just building things and finishing things, you get to experience a wider range of problems and solutions.
Destination Unknown
To me, this was the most important point. But what do I mean by destination unknown? Well, the first group did not know what the perfect pot would look like or how to make it. They did not know what would make the pot collapse and what would make it beautiful. They had a vague idea of what they wanted to make it but lacked the skills to get there. So, by focusing on building the perfect pot, they did not get the opportunity to learn as much. The second group, on the other hand, started out in the same place but through trial and error they built on their knowledge. They were free to experiment and refine their process as they went.
The same applies to software development as well. Jumping in and building things lets you discover how a solution should look and how to build it. As you progress and encounter real issues, you can find the solutions as you need them. This is a much better way for us to learn, as we can see the reasons behind them much more clearly. You also don't need to solve everything upfront, which may be too much to hold in your head at one time. It's impossible to exactly know what to do upfront, you have to discover it along the way.
The first half of the pottery class spent hours on a single pot, throwing it and rethrowing it. But by the end, none of them had made a perfect pot. Students that had to make 50 pots, on the other hand, made so many pots that they figured out what worked and what didn't. By the end of the semester, they could all throw a perfect pot.
When writing software, the only time I knew what I should have done is after I've already tried something. You can't think of everything upfront. The best way to learn something is to try and do it.