When faced with a new problem, we start thinking of the different approaches we can take to solve it. We look back on previous experiences, and see if we've solved anything similar in the past. If so, maybe that same type of solution can be applicable to the current problem. If not, maybe it can be adapted. Pattern recognition can be a powerful tool to help us solve problems.
But with our previous experiences come our own biases as well, directing our trains of thought. If my previous problems all had a large focus on security, chances are high that I'm going to be keeping security in the back of my mind. While this is beneficial for preventing security holes, it can also work against us if I try to inject sophisticated security mechanisms when they aren't needed, just in case.
It's important to remember exactly what we're supposed to be building. Who is it for? What are they going to be doing with it? Is this new feature going to help? Is it necessary? The more frills we add on, the greater the chances that the motivation for what we're doing will be lost. Programmers can have a tendency to make things more complicated than they have to be.
At the onset of a project, this is easier to keep in mind. But as time goes on, we keep our heads deeper and deeper in the details, and we can lose the forest for the trees. We add tweaks here and there, spend some time on peripheral tasks, and then get caught surprised wondering why it is we're so far off mark.
It's important to note that what we're building can change over time. In fact, if it's a long project, it probably should change. If not, what we're building may no longer meet its demands.
So when we're lost, we should remember to take a step back, take in a deep breath, and ask ourselves what we're supposed to be building.
Ask a programmer to hang a picture frame, and you'll get a new wall instead.