This article was written jointly by Anne Currie and our CTO Pini Reznik.
In 1979 a US architect called Christopher Alexander wrote two best selling books that proposed a different way to architect cities, streets and homes. The books were called “A Pattern Language” and “A Timeless Way of Building”. The approach to design and architecture that he described has had a persistent following in the tech industry ever since. What’s so interesting about it and why has it captured our attention?
Architecture: “The complex or carefully designed structure of something”
There is a reason that we apply the term architecture to both buildings and computer systems. The word implies a non-trivial system whose shape has come about through careful thought, imagination and planning - also known as design.
When we design and plan something, whether that is a house or a microservice, we usually bear three things in mind
What Alexander pointed out was this is just table stakes. For a system to be truly well designed it must also serve more human needs:
He called this attribute of rightness, “the quality that cannot be named”. His assertion, however, is that that doesn’t mean we can’t understand it. In fact, every human can recognise this quality when they see it. They just need to trust their gut.
We’ve all seen houses or cities that feel right, that we’d like to live in; and we've seen ones that feel wrong. Alexander points out that “right” does not necessarily mean classically beautiful. A gorgeous city square with no shade from the sun or comfortable seats will not throng with people (except those briefly passing through). No one wants to spend time there. An intimate courtyard with a welcoming cafe, a mixture of sunshine and shade, a well maintained tree or fountain might be a far more human location - a place people will be happy to spend their time in and maintain.
In the same way, as software engineers we have all experienced computer systems that are inhuman. That constrain us, frustrate us. That are brittle and don't support us as users or maintainers. We’ve also hopefully worked on systems that have made us proud, that have been a genuine pleasure to develop and grow.
At this point you might be expecting me to say that Cloud Native systems are innately more “right”. Unfortunately, that isn’t true. Cloud Native systems: containerised, microserviced, orchestrated, are no more innately likely to exhibit rightness than a monolith. In fact, in many cases they can be worse.
The truth is that being Cloud Native isn’t a silver bullet. In fact, Cloud Native systems are innately complex. This can mean they have a high likelihood of failing to deliver even the table stakes of good system design: being fit for purpose, stable and efficient. Sometimes a monolith will be a better architectural move or one Cloud Native approach might be better than another. All design choices are context-specific. There is no one design that will work well in every circumstance.
What kind of contexts should we consider when making design choices? There are a lot! For example:
A design that ignores context will almost certainly be a painful one to deliver and live with.
Alexander’s solution was to come up with a set of good, context-specific design patterns for building that were easy to explain and teach; and deliverable. For him, these patterns were learned through a long career and observing what did and did not work on the ground.
The same approach can be applied to Cloud Native. We now have enough examples of good design to start to define what works in what circumstances.
A pattern is an ideal design to address a particular need expressed in a single, descriptive title. Each pattern fits into a larger scheme of patterns that rely upon it (sub-patterns) and patterns it relies on (super-patterns) and others that are complementary. Together the full set of available patterns for addressing a particular type of architecture form a language. A way to simply but fully describe a complex system.
Just like Cloud Native in general, each pattern is not a magic solution. It is context specific. Also, as Alexander stressed, patterns must be delivered well: carefully, committedly and with a high degree of skill.
Patterns are not a hack. They are not a quick and easy way to solve difficult problems without careful thought. Instead, they are a language for sharing context-specific best practises.
Alexander said that “each pattern can exist in the world only to the extent that it is supported by other patterns”. A design is incomplete if it doesn’t contain mutually supportive patterns to address the entirety of the system from the largest problem to the most detailed. In addition, he concluded the overall vision cannot be delivered in one big bang, but must grow towards the envisioned ideal.
In the same way, the patterns of Cloud Native must combine together. For example, a “Distributed System” may depend upon “Modular Architecture”, “Encapsulated Applications” and “Dynamic Scheduling” and be part of a a larger goal such as a “Highly Secure System”. We’ll describe these patterns and how they fit together in later posts.
The point of a pattern language is to make it easier for developers to discuss, learn and apply the best practises in Cloud Native; and replace expensive Cloud Native consultants like us!
In the rest of this blog series we’ll attempt to seal our own doom by sharing the Cloud Native design patterns that we've learned from over three years of helping enterprises move to Cloud.
Read more about our work in The Cloud Native Attitude.