The missing point of reference
Maintenance can be difficult even when you know the structure of the code and data and why it’s built the way it is. When you are looking at unfamiliar code, it can get much harder. Why is this so? We can walk into almost any house in our neighbourhood and expect to find features in common with our own homes. The design is shared. The design is settled. There’s a long lineage of small adjustments to the design of houses over the ages, but standard components have remained unchanged for centuries. With code, however, so much of the design differed between similar programs, familiarity was highly unlikely. I use the past tense here because things have started to change.
In a house, we don’t design bricks, windows, stairs, or doors. They are the raw materials in most modern homes. Instead, we lay out the rooms and dress them. But there’s only really one layer to the design. In code, we don’t design the assembly instructions, the standard library of our language, or the operating system it’s running on, but we do create layers of design above them all. Your to-do list app will be a UI layer on top of a business logic layer that sits atop a CRUD1 model, which may sit inside or on top of a database access layer. These common layers are familiar to many. They feel like home, so when you find out someone has built something without using them or using something different, it feels alien.
Ancient Greek literate programming
In the past, we lacked these standard materials. We only had bricks. Even though many languages are vying for attention in the full-stack space for developing web, mobile, and desktop applications, they all share similar development and deployment patterns. The request routing, database-backed, CRUD-based, event-driven, model-centric approach to transactional applications is a pattern language. It’s not beyond unreasonable that The Twelve-Factor App could be a pattern language. These layered designs, which we instantly recognise, are the closest we have to classical Roman architecture.
Unfortunately for software developers, these programs only make up a portion of the programs written today. Most embedded development uses a different model. Desktop content creation tools have a different model again. Almost all computer games have a very different structure, and there are many different types of game leading to differing sub-structures at that. There are many other domains with similar stories to tell, far more than I know of, I’m sure. Programs for each domain tend towards a particular style of architecture, but there’s no universal pattern language. Each domain has its own.
This means that for software, there is no singular pattern language. There are many. The search for software patterns and a software development pattern language was doomed to fail by starting from a paradigm. A book on the design patterns of object-oriented design would be like an architectural pattern book on working with bricks. A paradigm is a method or tool you can use to solve your problem; it’s not a problem in itself2. The benefit of patterns was a design process unencumbered by a specific solution.
Why are there so many domains in software when there was only one domain in
architecture? Well, the secret is, that’s a false assumption. There are many
domains in architecture too. The book is called
Let us finally explain the status of this language, why we have called it “A Pattern Language” with the emphasis on the word “A,” and how we imagine this pattern language might be related to the countless thousands of other languages we hope that people will make for themselves, in the future.
— Christopher Alexander,
A Pattern Language , p. xvi.
In many of his projects, Alexander selected and generated patterns constituting
a specific language to guide the development.
For example, in
In [Battle12], the pattern language is presented quite differently to that of [APL77]. Gone are the cute, terse names of the older patterns. Instead we have simple but to the point sentence sized descriptions with extended paragraphs to fully enclose their ideal. I saw this as positive progress for patterns simply because good names are impossible to find.
The patterns in
Software inhabits domains too. Each program generally belongs to one domain. The desktop application, the performance-critical batch processor, and the highly available network cluster management software each have their own pattern language—their own collection of patterns found in the development of a cohesive system within their specific domain.
But there’s absolutely no mention of this aspect in the GoF book[GoF94], and it’s only lightly touched on in the first
Later works reside in different domains with many patterns that help guide you through creation or transformation. Examples include:
React Design Patterns [React17]Node.js Design Patterns [NODEJS16]Language Implementation Patterns [LIP09]A Scrum Book: The Spirit of the Game [AScrumBook19]Patterns in Game Design [PiGD05]Cloud Native Transformation [CNT19]
But other pattern language books, such as
In both books, there was no product, no building to inhabit, only the minds and culture of a group to transform. But they are pattern languages because they take commonly repeating problems in their domains and provide details on the types of solutions, the consequences, and how they fit into other patterns.
Without pattern languages, it’s difficult to find your way into patterns. It’s hard to find the right place to start when every pattern implementation starts and finishes without an apparent next or previous step in the sequence. The absence of a higher-level pattern structure or a dependent consequence of pattern application leaves the user stopping and starting, lurching through development.
CRUD stands for Create Read Update Delete, the fundamental activities in a database. The term turned into a way of thinking about what you need in any record-keeping technology—a way to insert new data, retrieve it, amend it and remove it.
I have strong opinions about OOP, but even I wouldn’t say it was a problem which needed to be solved.