Hobbes wrote:
I agree with the OP for psychological reasons. Every time I try a bigger project, I fail because I keep adding features and optimizations in the middle of the process. Then I loose the overall picture and delete my work and start all over.
You shouldn't usually start all over, but much less should you ever delete your work. Even if you find yourself in a situation where you need to start over, it's good idea to keep a copy of the old stuff in case you need to refer to however small fragment of it later.
Unless your development method is to write code, see if it works, and start over if it doesn't (that is, to never debug anything), your previous versions almost certainly contain a lot of accumulated information, which can be helpful later.
Plus I actually don't believe in starting over at all. Even the largest redesigns can usually be done by some form of refractoring. Avoiding feature creep and optimizations is one thing, but unlikely to be the real reason why you fail: more likely you keep adding the features and optimizations without adapting the rest of the design. Once you discipline yourself to always properly refractor rest of the design to accommodate the extra features and optimizations, you gain two benefits:
1. Your code stays cleaner and easier to work with when new features are integrated properly by changing the design rather than by finding a way around it it.
2. Resisting feature creep gets easier when you learn to count the "time-to-restructure" into the cost of adding a feature. I think this is the biggest benefit.
Sometimes you do need a rewrite, but even THEN I'd really reuse as much of the old code as possible.. and usually that's a lot.
Quote:
Knowing in advance exactly what the program should do and do not, really helps me stay focused.
Unfortunately, that never works for any larger project, because actually the whole idea of "design first" is rotten: the act of programming itself is part of the act of design, and you don't have a complete design before you have a working program.
That doesn't mean you shouldn't start with the big picture; you probably should. But pretending that you can do complete design, set it into stone, and then go implement that design without having to go back and adjust the big picture is not going to work well: you typically end up with features hacked together to work around the limitations of the design, rather than with a system where the design enables the features naturally.
So I personally suggest: do a big picture design, but as soon as you notice the slightest problem with it, stop writing code, go back to the design, see how much you need to adjust it, and then do the adjustments in code. If you learn to do such adjustments as soon as there is a need for them, it's actually rather easy to keep the code workable no matter what you need to do with it. Sometimes you need small changes, sometimes you need huge changes like turning the whole control flow up-side-down or inside-out. But very rarely you actually need anything as drastic as a full rewrite.
Anyway, that's just the personal thoughts after some 15 years of banging my head against the wall. YMMV.