I agree that all these are a pain in the ass. But they are NOTHING compared to back-end architecture. During my over 10 years career as a software architect, I’ve seen significant improvements in nearly every parts of back-end architecture but it’s still very hard. The fundamental difficulties are still there, nearly unchanged all the time. Let me list some of the major ones.
Design for failure. Nearly half of the back-end code are not for ‘common’ situation. They are designed for failures. They are designed for letting the system provide acceptable response under special or extreme conditions (and within specific budget): too many concurrent requests, the memory runs out, a new node is being hot-plugged in to the system, the load balancing device stops working, the long connection breaks every several minutes for no reason, etc. To maintain such functionality the design should contain many compromises: sync or async? Scale out or scale up? Realtime transaction or batch job? etc. All these tradeoffs cannot be determined through any simple rules and must be considered via all aspects of environment and requirements of a dynamic system. It nearly always leads to some kind of mistakes.
Architecture is about abstraction. Why abstract? Because abstract concept/mechanism/pattern/methodology provide far more flexibility and reusability. The progress of abstraction distills the essence of the problem and wrap it as reusable component which can be used to solve similar problems in completely different system/context. Seems beautiful isn’t it? But unfortunately, abstraction is hard. More unfortunately, inappropriate abstraction is incredibly disastrous. And the most unfortunately, we have very few working methodology to do abstraction. Abstraction is a kind of art, remember? Mostly we begin with several general models, walk through a series of key rules and continually test our design for the lifetime of the system. Very experience based. In many cases when we find an architectural mistake it is too late. All we can do is to choose from the options between rebuilding the system from ground up or doing the yucky patchwork until we are exhausted.
Architecture IS product. A software product contains many different point of views. Two of the most important are the end-user point of view and the architecture point of view. The end-user POV is like a black box, described by system input and output, can be (relatively) precisely defined and tested. The architecture POV is from inside the software system, the blueprint of the system as a whole, mainly describes each of every parts of the system and the connections between them. In most cases there is no direct link between these POVs. So those are very different POVs but they belong to the SAME product. They must be kept aligned and consistent. So the architect must deeply understand the soul of the product and the product designer must know the capability and limit of the architecture. Otherwise (i.e. the common situations), either the architecture has to be changed tremendously to meet some normal new product feature request, or after implementing a high cost product feature it appears that this feature can be replaced by another easy one which can bring the end-user nearly the same value and experience.
Well, there are more but that’s enough. I consider all the above are the ‘essential difficulties’ as defined by Frederick Brooks in his epic No Silver Bullet, which means no quick solver in the coming future.
Back-end is hard. Q.E.D.