Suffice it to say, I spent all of last week developing a new feature for Querki called "User Values" -- the ability for a Thing to have a different value for each User. (Which we're going to use for things like Reviews.) The code was hairy and ornate, and by Friday I was tearing my hair out over the complex interactions between it and some other features, especially Model Types.
And then, Sunday morning, I woke up with the horrible epiphany that I'd done it all wrong -- that I'd made a decision early on, that seemed to make sense at the time, but had made the problem ten times harder than it needed to be.
So this morning consisted of disentangling all of that ornate new code, putting lots of things back to where they were, and (the inspiration for this post) simply deleting the complex new class that was at the heart of it all. I've replaced it with an alternate design that is slightly less "magical" at the UI level (you need a few more manual steps, instead of the system DWIMming quite so much), but is semantically cleaner and *vastly* more robust. All the things that were so hard to do previously turn out to simply work correctly with no code changes in the new design.
The point is an important one, and it's one of the common differences between junior and senior programmers: you have to learn to get your ego out of your code. Yes, you spent a ton of time on that; yes, the design might be a thing of beauty. Doesn't matter: it's sunk time, and no longer relevant. If it isn't what you actually need in the code base, just kill it and move on. It'll be better for the program in the long run...