Concentric Circles for System Design
Originally published @ samxsmith.com
I’ve been building and maintaining software for a while, and the rules of design are visceral: I feel that something is sensible, or problematic. As I spend more of my time mentoring & leading others though, it becomes less important to know what is wrong or right, and more important to be able to communicate ideas about good design in a slightly more formal way. Because my decisions had become instinctive, embedded, I’d lost some of the ability to explain what I meant and why. Certainly, the principles ingrained in me had long since lost their English translations.
To solve this problem, I revisited a (not-so-old) classic, Clean Architecture by Bob Martin. Bob’s discussion of layered design in that book is fantastic. Clear, yet broad and virtually universal, it is still the mental model I use.
In an effort to cement my ability to communicate these concepts to colleagues and friends, I wanted to get some reps in here.

What is layering?
Layering is an arrangement of dependencies hierarchically, stacked or encapsulating one another. Each layer is distinctly separate, rather than intermingled. Each layer can only communicate with the layer above or below it. This creates increasing levels of abstraction.
We generally divide layers based on the level of generality vs specificity of the work each does. This will become more clear as we get to concrete explanations below.
Why layer?
Firstly, the formal separation which layers enforce makes maintenance much easier. We can manage stability per layer, and clearly define the dependency graph. Each layer does a certain job, extending the single responsibility principle.
Layering makes the connections between levels of specificity explicit. We can manage this coupling with interfaces, producing a layer-to-layer abstraction, to allow easy extension and substitution. The result is a system of self-sufficient layers, that can do their part, and then hand off to the next layer.