"You can't polish a turd"There's always a point beyond which a particular class or module should just be tossed out and re-written, rather than fixed. A point where something's gone so badly in the wrong direction that it needs to be humanely put down so we can get on with the rest of our lives. But when to start over?
Only the developers who've worked in a given area know really how horrible it is, but even then it's hard to get an objective opinion. Many developers are over-precious, defensive of their own code, and unduly negative of the work of others . Then again, other developers 'at the coal face' can be blind to how screwed something is, happily chiselling away when it's time to grab the dynamite. Even the system's architects can fail to grasp just how unworkable it is from a grunt's perspective. Management just can't win.
Here's some pointers to identify 'start over' candidates:
- It's going to cost more to fix than to build from scratch
- It's going to be quicker to fix than to build from scratch
- There's a high defect rate in that area
- There's no test coverage in that area, so any fixes walk a regression minefield
- Even when fixed, it'll be sub-optimal compared to building from scratch
- Even when fixed, it doesn't really do what you need it to
- Even when fixed, it imposes significant architectural constraints on the rest of the system (eg perpetuates a coupling you're trying to get rid of, or continues with a depricated metaphor)
- Even when fixed, there's a significant maintanance cost
- There's no-one left on the project who understands how it works, yet it's not stable enough to just leave alone, or was left half-done
- There's no documentation
For the sake of completeness, all of these can be applied at the project level too. This is a really tough call, but sometimes a clean break is for the best. Salvage what you can and move on. The most reusable part of a project is always the IP anyway, not the implementation. Even if you don't reuse one line of code, you'll still have learnt something.
 It happens to us all. Every so often I find myself panning code I wrote myself (and subsequently forgot about)