Here's another twist on the good advice above. Right at the start of all the big projects I've done (I confess - this is not very many) I write a description of what it's going to do in language my mother could understand. Something like
After I've done that, I usually find that I've exposed any stupid assumptions I was hiding under technical generalisations, and I have a pretty good idea of how it breaks down into subroutines (and where code re-use is likely to happen). And as a bonus I have the basis of a pretty informative set of comments to imbed into the programme.