One of the principles behind the Manifesto for Agile Software Development is Simplicity:
Simplicity--the art of maximizing the amount of work not done--is essentialIn other words, keep it simple unless there's a current requirement to make it more complex. Don't try to design for some possible future requirement, design for what you know today...for what features are in the current iteration or release.
I've had architects that have struggled with this idea. They would argue that you need to come up with a comprehensive design up front. However, if the requirements aren't known completely (and when are they at the start of a project?) doing a full design will be challenging. I've seen organizations get caught up in analysis paralysis and have trouble getting anything built.
The key is to plan to the appropriate level of detail. At the beginning of a project there are a lot of unknowns, so a detailed design isn't practical. Focus on a design to get you through the first iteration, or maybe the first few iterations that make up a release. Know when you need to refactor.
What can change to require code to need refactoring. I can think of a couple situations;
- Change in requirements - Everything changes. As business needs change and evolve, the programs to support that business need to change as well.
- Change in technology - What technology are you using today that you weren't a year or two ago? Look at how popular devices like tables and smart phones have changed the the way people work and interact.
So what does this mean? The need for refactoring will always be there. I often advice clients that it's better to get a first release of an application to production as quick as possible, even if it's not perfect. You will start receiving some business benefits and it will give you better ideas on how to improve it.