The longer your application exists and being actively used, it will probably change as users want features added or changed. Faced with this, most developers will try to design application for the future changes. We may start writing code that is not needed but we write it anyway to make it future proof. We cannot exactly know how our program will evolve over time and all the extra code we write may become unusable.
Another mistake made by developers is writing the code that is rigid in structure and not easy to change. It makes sense to spend some time during the design phase and pay special attention to code maintainability. Most programmers will end up maintaining code written by someone else and it is a nightmare to maintain badly designed code.
We may also be inclined to over engineer and be too generic, thinking that we can make any future changes easily for all possible situations. You can end up writing a lot of unnecessary code to be generic. It is perfectly fine to spend time designing a good solution but if you feel that your design is making things more complex than they need to be, you are probably over engineering.
This is where Agile method of incremental development and design can help. Agile development requires less time and effort by designing system piece by piece instead of designing the entire system upfront. We can easily update design with every iteration and add new features.