I was particularly incensed by a talk about software architecture, and how to do it right, and I've been mulling over in my head the best way to explain why thinking about software architecture in that way is wrong. Here's my take on it.
If you think about software architecture as a bunch of interconnecting boxes, you’re doing it wrong. At best, it’s just design. At worst, it’s wishful thinking. You’re not really saying anything meaningful about the boxes or their relationships or connections. You’re trying to describe a city in terms of its big buildings. But big buildings do not make a city.
Rules make a city!
One thing I really like about Fielding’s REST architecture is how he describes “architecture”. He says:
There are two common perspectives on the process of architectural design, whether it be for buildings or for software. The first is that a designer starts with nothing--a blank slate, whiteboard, or drawing board--and builds-up an architecture from familiar components until it satisfies the needs of the intended system. The second is that a designer starts with the system needs as a whole, without constraints, and then incrementally identifies and applies constraints to elements of the system in order to differentiate the design space and allow the forces that influence system behavior to flow naturally, in harmony with the system. Where the first emphasizes creativity and unbounded vision, the second emphasizes restraint and understanding of the system context.
Beautiful! In short, architecture is a bunch of rules which define the boundaries of what you can do. They do this with a list of things where you can only do those things, or a list of things where you can do everything except those things. These work as a list of axioms, things that hold true no matter what, by definition.
Good architecture should be a checklist, not boxes!
The reason you do this, in general, is that constraints are effectively the same things as abstractions, and you wish to express your desire in the most concise (hence abstract) way possible. To re-state that somewhat, only being able to do a particular thing limits what you can express, hence allowing you to “compress” that expression and make it more abstract. The important thing is to align these things so that the things that constrain you aren’t important, and the things that you care about are important.
This can be stated more exhuberantly
The point is, all of architecture, and “how do you architect things” cannot be generalised better than that. “Computers compute”, and that’s all there is to it. Saying “all architecture should be X” is never true.
There’s precisely one exception to this: hardware! I’m not talking about specifics, although they matter as well, but I mean more at the level of “Von Neumann machines” or “networked machines”. Software people actively try not to think about these as part of the architectural “stack”, but in fact these are precisely part of the architectural stack! There are electrical abstractions that create logical abstractions that allow us to construct mathematical abstractions. We are not more literally constrained than the hardware.
After all, it’s no use if your virtual machine can do something in O(1) time when your hardware is doing it in O(n) time. These things need to line up! I’m surprised then how few architectures line up according to that paradigm. Almost every architecture that works splits design up into memory, computation, and IO. Occasionally, “memory” and “computation” will be linked, but the implementation is better when it is not. Managing state is another major theme, especially on the web. REST addresses this particularly well, yet everyone is out to “implement REST” but then violate every REST axiom. That’s basically saying "there is no architecture."
That’s really it! “Architecture is axioms which define constraints”. If you say any more about architecture, like thinking about data flows or componentisation or re-use or versioning, then you are wrong in some cases. You are most correct when you try not to violate the constraints of the hardware architecture, which your software architecture sits on top of, however much you might dislike that. Violating an axiom of the architecture is the same as saying there is no architecture. Amazingly people find these things hard to do and then go about trying to figure out how to draw boxes in a way that they will no longer have problems. They are looking at the wrong thing.