I keep coming back to this opinion piece, so I have decided to quote it here in its entirety here. It argues that often times, software is made more complicated than it needs to be.

No! Your software is complicated, not complex.

"Far too often I hear from developers that their software is complex, but when I look at the code that is written, and understand the problem it is trying to solve, it is nearly always been made complicated.

Most problems are pretty simple, and this is evidenced by the fact that the real world continues to work by human processes and workarounds which if they were truly complex would be too hard for people to remember. Yes, there are some truly complex systems, but the vast majority of what most people build is a workflow process replacing paper. Not complex at all, but terribly easy to become complicated.

What normally happens is that looking at a problem, there is not enough separation of concerns and concepts become intermingled, leaving the impression of complexity, when in fact, the wrong problem is being solved, and the workarounds required create a mess of complicated code.

In Eric Evans' book, Domain Driven Design, he mentions this, and notes that when you find that situation you are nearly always missing an abstraction. So, if you are finding that your code is complicated, the first thing to think about is "do I understand the problem well enough?" and then "am I missing something here that will simplify my code".

Complex domains shouldn’t end up with complicated solutions. Complicated solutions are a design and implementation smell to be avoided at all costs."