Many years ago, back when we read the fourth chapter of Spring of Change, we said that Change does not happen for no reason. Each Change has a predecessor, called a Cause. First there is a Cause, only then there is a Change. Causes also do not come out of nowhere, they have a Source.
We’ve put aside what the Source exactly is in order to keep our design aware that a Source exists and remain agnostic to it. Our application does not care whether it was the CEO who Caused an Engineer to Change or if it was the Engineer’s mother.
In this chapter, we’re going to see what the Source is. More than that, we’re going to see what the Change Stream is.
We kind of already know, or more correctly to say we presumed that a Product Manager is a Source for Non-Technical Causes, specifically Product ones. He is the one issuing Causes that later the Engineer transforms into a Change. In the previous chapter, we’ve seen that a Product is an entity composed of other Products and Features (which we generalized as Flows). We’ve also seen that Features grow into Products through time. Let’s put both of these insights into a single diagram.
With it, the Source mutates. The Senior PM is hiring a junior one. Both are now issuing Causes to the very same Engineer. Some would be conflicting of course, as everyone suffers from tunnel vision. As time goes by, the Feature that has grown into a small Product has grown into a very big Product. With it, it got a dedicated team of Engineers, who now needs to decouple the intertwined Products. A Source of a single PM has mutated into two independent Sources of two PMs.
These mutations are exactly the reason why we designed our application to be agnostic to the Source, as much as we can. We made sure these mutations would not affect any Directions of Change at all. Directions come out of Causes, not out of Sources. Causes do not care whether they were issued by a PM called James or a PM called Jimmy. Whoever issues them, the Change would go through the same Direction. Same goes whether it’s an Engineer named Will or Bill. Same goes when one of them eventually leaves, and someone else takes over it and hopefully he’d been properly on-boarded.
We’ve seen one very big Source mutation before, a company going through reorganization. If our design is agnostic to it, there is less of a need to align it with the Change Stream, if at all. We’ve probably saved a lot of work for The Architect.
Let’s review the three Technical Causes we’ve found in chapter 8, Collision of Causes. Back then, our application had three external dependencies. Stripe, our DB and a 3rd party Notifications vendor. We’ve seen that each one has a completely mutually exclusive cluster of Causes and is a clear independent cut of the Source.
If we notice carefully, a Change within the Source is our Engineer’s Cause! A Change in one layer, is another layer’s Cause.
Our DB, who is a few years old by now needs to be replaced from MySQL to Postgres. For our application, it would go through the DB’s Direction of Change. The DB’s Change is our application’s Cause. The DB’s Cause is a scalability issue.
All the way over at Stripe, a Change has been applied by an Engineer, Caused by his PM. That Change has been reflected in their HTTP API, which now our application has the option to consume and use. We knew nothing of it, until one day our PM had an idea for a new Feature. He read’s Stripe documentation and sees that the newly available option is mandatory for this new Feature, a prerequisite. Coding this new Feature would require two small Changes instead of one Big Change.
One of which would be a Change going through the Product’s Direction of Change. It is clear that it is a Non-Technical Cause and its Source was the PM and his new Feature idea. But that is the second one needed, the first Change would go through Stripe’s Direction. But is it of a Technical or Non-Technical Cause? Is Stripe the Source or the PM? The answer is a superposition between the two, and it does not matter. It’s a mere coincidence.
The story could have gone otherwise. Our Engineer might have already applied the required Change to our application, because he had to upgrade Stripe’s Client for some other Cause. Although far beyond his control, it could also have been a Change Stripe did due our PM’s request!
In the first story the Source was the PM, in the second story the Source was Stripe. Same Direction, same Change. In both stories, first a Change had come through Stripe’s Direction and only later another one through the Product’s Direction. The real difference is how much time passed between the two Changes. Only in the first story, the two Changes were consecutive. Exactly what our application is agnostic to.
Our Directions of Change remains the same no matter the Source of Cause. That is the complexity of the Source, it varies, it is time dependent, sometimes coincidental and it mutates.
Use the Force
Our application’s DB is within our company’s control, could even be operated and managed by the very same Engineer who codes our very own application. If the Engineer goes ahead and applies a Change to the DB, from our application’s point of view it was a Cause. If one layer’s Change is another layer’s Cause, and the DB is within our control, that would mean it is not a Cause-Change cycle, it is a Change-Change cycle!
Our PM with the new Feature idea, was a Cause for our application. But it was also a Change to the User Journey or the UI/UX design. Same goes for Stripe’s PM. He Changed a design which entailed a Change to Stripe’s API which eventually entailed a Change to our application. A Change-Change-Change cycle that just went through multiple companies. And let’s not forget that a Change to an application is a Cause for deployment which is a Change on its own.
So it seems like there is an end to it, but where does it begin? Our PM’s and Stripe, made a Change because there was a Change in customer demand, satisfaction or expectations. That happened because PayPal made Change, introduced a new Feature and Stripe just wanted to keep it with their competitors. And so on, and so on, and so on. How far can it go?
Try to remember the first Covid lockdown, all the way back to March 2020. The world had suddenly Changed almost all at once. That had Changed the economy beyond recognition, which required multiple companies to Change their economic models and Products. To pivot. Which was a Change to designs, which is a Change to applications, which is a deployment which is a Change. A Flow of Changes. Change entails Change.
That is the Force of Change. That is The Change Stream we introduced all the way back in the first chapter of this series. The one we worked so hard to make our application’s agnostic to its unsteadiness. Because everything Changes all the time, everything is impermanent. Now that we better understand what the Source is, maybe we can start calling ourselves Software Architects, because that is what they used to do. Align between business flows and applications. I’m still not sure what Architects do these days.
Does the Force of Change really exist? It is a recurring model in several philosophies. If you ask Carl Gustav Jung, he’d call it Synchronicity. If you’d ask the Dalai Lama, he’d call it Karma. If you’d ask a Software Architect, he might say it sounds like a generalization and the basis of Event-Driven Architecture. There was another great philosopher who talked of this interconnectedness through time, but he had later became a Nazi so we better take it with a grain of salt. Exactly why it should be treated as a beneficial model, one out of many, and not a belief.
Future of Change
In this series, we’ve made our application better handle the frequency of Change and its distribution, and the unsteadiness of the Change Stream itself. The modeling of the Change Stream also as a Force of Change opens us up to learn how to control Change and its frequency. As Change does not happen for no reason, between any two Change-Change cycles there is something in between that is almost entirely within our reach and control. But that would be further explored in Projection, section 4 of this book with another model called The Wheel of Change.
Let’s not forget that Change itself is the fuel of the erosive evolutionary processes. By giving in to this, we’ve modeled our application to withstand Change. The result would be slowing down some of those. We slowed down the evolution to a Monolith and slowed down the evolution to a Bundle. Both may postpone the evolution to a Refactor. And we’ve seen that because things like Hardware and OSs are beyond our control, we can also slow down the evolution towards a Legacy but only a little.
But there is a lot more to do in order to further slow these processes down, because we’ve only slowed them down for a single application. In the next series, Breaking Change, we’re going to take these very same principles into designing multiple applications, and see what hastens their erosive evolution as well.
Thank you for reading this series!