Stability through structure preserving change
However, this idea that a pattern is a static form did not align with
Christopher Alexander’s works. It’s not how he described patterns in
Before I came across this book, I was stumped to find a way to marry the 15 properties to software development. I had only recognised a few properties, such as repetition with variation and hierarchy of refinement, and some from my preferred paradigm, such as decisions made early and request actions, express interest in state. The value in both refactoring books was in the inspiration that I could find these properties from their constructive steps. When Alexander discussed the 15 properties, he was never far from describing how the property arrived. Each property came with a process to create it from what was around it or was a byproduct of a wholesome process. If the same properties exist in software, they may undergo the same type of transformation. This means they will likely turn up during refactoring or in regularly repeated feature development processes.
Refactoring, with patterns in mind, is an unfolding sequence. Because refactoring is not meant to change behaviour, it is structure (or value) preserving. What’s fantastic is that this means we have two positive outcomes. Pattern refactoring allows you to migrate an old codebase towards a better state. It also suggests thinking about patterns can be put off until later. Refactoring always applies to existing code, implying you don’t need to figure out what patterns to introduce until later. Don’t take this as a suggestion to avoid any up-front planning, but you can stop beating yourself up over not realising you needed a pattern until halfway through a project.
Scale
As a project grows in size, neighbours become distant acquaintances. The original project may have had one developer, then a team, then teams. Refactoring good quality systems into larger ones is always much more successful than creating a large system from scratch. Refactoring appears to be the only way to unfold a system of code. Rewrites don’t carry any of the lessons learned in the code; those exist only in the fallible minds of the team developing the replacement (this is assuming the team is the same as the one that created it; a fresh team is hopelessly cursed to reproduce eerily similar bugs the second time around).
Why is this the only good way to develop a large system? It’s a simple case of
acting on incomplete data. In
All these changes are only required after many rounds of returning to the experts to get their evaluation of the system once it has been designed or even implemented. A non-expert can only deduce some of the interacting objects and activities they are involved in before writing the first lines of code. We cannot expect the experts to know what they weren’t sharing due to the curse of knowledge2.
The information about how the system should work was always there, just as the laws of physics, the materials, and the landscape upon which a building is built are all there from the first moment of the contract. And just as Christopher Alexander found, even with all that information, the solution is intractable for the human mind. It needs augmenting with processes and tools—a piece-wise process of experimentation, evaluation, repair, and remodelling. In code, this is an iterative and incremental refactoring process.
Architecture needed a way to introduce new features incrementally and evolve the design and implementation. What Christopher Alexander developed was the process of unfolding.
Even though the GoF book does mention the patterns as targets for refactoring, it’s near the end of the book (p. 353) and not introduced as a step for each pattern, so it’s easily overlooked.
https://en.wikipedia.org/wiki/Curse_of_knowledge the failure to consider how much you take for granted. Like how old programmers, upon observing a limit of 255, assume something about the implementation, but non-technical people would have no idea what that would imply.