Yes, definitely. There are too many diligent and too few lazy programmers. Too many devs take pride from coming up with complicated, overengineered abstractions – after all, if they can manage the complexity they must be really smart, right?
Eh. Sometimes over-engineering is a matter of perspective.
Take JSON API, a standardization of HATEOAS / REST principles around JSON and HTTP, for example. If you just naively walk up to it you think to yourself:
> Wait, what? Can't we just return the simple data we know we want? Why complicate this all with relationships, links, and meta data?
But after a while you realize that 90% of what you're doing could be abstracted if only you had a predictable output. So EmberData comes along and you write a Rails backend that has the nice advantage of not needing to worry about HTML (outside of OAuth / emails, anyway) and you harmonize your API. You use Ember Fastboot for slow clients and call it a day.
Someone else looking at what you've done may say:
> Wait, what? Why don't I just create static HTML pages instead of using your over complicated service?
And they're not completely off-base. In fact it's what I do for my own personal site. It's just that the context of their situation has different tradeoffs.
The same thing is true for a lot of software. Excel is "over-engineered" for most people. So is HTML. So is Unix. But in general what happens is that the person with the most complex requirements usually wins because they usually have the fattest wallet and everyone else papers over the complexity with abstractions or uses something less complex that meets their needs.
The Unix Hater’s Handbook [1] is a pretty good read (or skim). It’s healthy to remind oneself that, even though unix-likes are a savior from the deeply unpleasant alternatives, warts are present.
>Too many devs take pride from coming up with complicated, overengineered abstractions
This is what I feel about the current JavaScript ecosystem. I feel like web development became popular so programmers from other disciplines (C, Java, etc.) jumped in and found it to be too simple so they've hijacked the ship and created a new JS ecosystem that is as complex as their old environments.
Coming from a (primarily Windows) desktop development background, I can definitely tell you that JS/HTML/CSS and the DOM is some of the most complex, over-engineered stuff to ever see the light of day. It seems simple, but that's because it was simple initially, and now it's grown into this monster that has very little design at all and is just piles and piles of APIs and code added on top of other APIs and code.
Desktop development is blessedly simple, in contrast. The problem is that desktop development APIs and UI toolkits have been neglected for many years in favor of web and mobile, so now desktop development is also a fractured mess because much of it is outdated or hasn't kept up with current graphic design and UI standards. But, at its core, desktop development doesn't struggle with oddball concepts like promises and other bizarre features that were introduced to overcome issues with the overall design of the language/environment.
It's more like this: all the work that was previously accomplished just on desktop apps is moving to the web and all the various camps that previously lived in their own language/framework silos are reinventing themselves in within the js ecosystem. If that happened in the historical silos, nobody would notice. But since it all happens on the common js substrate, we see the big mix.
We need to establish a rigourous and quantifiable definition of software complexity otherwise we can confuse complexity for misunderstanding the difference between essential complexity and accidental complexity. Remember intuition is not the same as simplicity!
From my experience, complexity to me means how many combinations of states are possible a program, how many paths one can take at any point, how many side effects are possible... etc. An abstraction is supposed to manage complexity, if it doesn't, that doesn't necessarily mean the abstraction is too complex, but that the abstraction may just not fit the problem or cover all the edge cases. Thus a leaky abstraction.
I have been saying for many years that overengineering is the plague of modern software. Almost everything seems far more complex than it needs to be.