Okay, so you know how they teach you, in Computer Science school, that lovely quote: "premature optimization is the root of all evil"? (variously attributed to Donald Knuth, or Tony Hoare, or other CS luminaries). Well, in my more recent experience, there's another programmer habit which is in hot competition for the evil-rooting title. I don't think it has as catchy a name, so I'm going to propose one here: Premature Flexibilization.
And here's what I mean: the practice of adding complexity to your code to make it more "flexible", in anticipation of future change.
Why would this be so bad? I hear you saying. I mean, we all know that software requirements change, so isn't it good to make your code future-proof, by making it flexible, able to handle those changes that are inevitably going to come? Most of the classic expositions of the glories of Object-Oriented programming are rife with this -- look, we're using abstract classes, so now the subclasses can vary, thus our code will be flexible and reusable, isn't that great?
Or, to put it another way: if you make something as absolutely damn simple as possible, then extending it along any axis is at least doable. But that's the only way.
Take a careful look at Design Patterns, that classic text of OO design. Notice how so many of the patterns are about making your software flexible, about making it adaptable to change. Then notice that all their lovely real-world examples are for frameworks which no one uses anymore. They've been replaced by other "flexible" frameworks (actually, they've usually been replaced by several generations of "flexible" frameworks, each of which turned out to be the wrong kind of flexible)
In contrast, consider the C standard library. It wasn't designed to be flexible, it was designed to be as simple as possible. And, lo, these 35 years later, it's still being used. Sure, it's been wrapped by other layers, improved this way and that, but it's still a live thing.
Also, note that "simple" is a very subtle idea. It doesn't necessarily mean "crude". Sometimes, the simplest way to do something is to, e.g. write a Domain-Specific Language--which is in no way trivial. But, and here's the key distinction, it's a solution to the problems you have right now. It's not a solution to problems you think are coming later. If you can train yourself into the deep habit of only solving today's problems, you'll be far better prepared for tomorrow than if you tried to look ahead.
What do you think? Agree? Disagree? Any examples that loom large in your experience?