In the previous chapter, we’ve used the principle of mutual exclusivity in order to find our application’s two main Directions of Change – Technical v.s. Non-Technical Causes. We’ve then reused that very same principle to further find Directions within the cluster of Non-Technical Causes.
That has defined a relationship for us. Non-Technical Modules are dependent on Technical Modules, and the second uses the first. We’ve then noticed it also defines the relationship between Technical Modules and Products. In order not to fall into another false dichotomy caused by our binary thinking minds, we’ve taken the first step into dividing the cluster of Non-Technical Causes to Products and Non-Products.
In this chapter, we’re going to try and define Directions within the Non-Technical cluster of Causes. We’d start doing so by understanding what differs Products from other entities, and then come up with another trick to reach mutual exclusivity between them.
Although based on true incidents I’ve been a part of, in order to tell a story let’s imagine an auction eCommerce website. Naturally, there are customers who sell items on the website and customers who buy items on it. Also naturally, our website looks kind of similar to them both. Less naturally, the company we work for has two development teams each one with its own Product Manager. One team dedicated to Buyers, the other to Sellers.
One day James from the Buyers team notices there was a drop in sales in the last few days. Luckily all Changes are logged and monitored and he quickly traces it. The Change was to the price’s color, turning it from blue to red. The Cause was that Jimmy, the Seller’s team PM, knew that red is more enticing to Sellers which would encourage them to put more items on sale. The Change was a Technical one, just like any code Change, but the Cause was a Non-Technical one. Let’s not forget Cause is the immediate Event prior to Change.
Two reasons have led to this. First, both the Seller’s team Engineer and PM suffered from tunnel vision. They only had the Intention to Change one Product, and could not anticipate it would affect the other. Second, they did not know that three years earlier, it was decided by a PM that the coloring of all prices on the website must be blue. A PM who had eventually left the company. The code simply mirrored that, due to cohesion. I’ve asked many what cohesion means to them, and many said “things that will change together, need to be together”. That is true and is the very definition of it, but maybe we need to also ask ourselves if they should.
Four months later, the alarms started ringing. Some metrics and KPIs of both teams started going insane. The last Change was quickly reverted and James once again quickly found the Cause. Once again our poor Jimmy, the Seller team’s PM, was not at fault. He was asked by the CEO to make sure Sellers can be given discounts on the company expense as a promotion. To do so, the Engineer tweaked the code of the Admin Panel. Hold on! what Admin Panel?!
Turns out our website has another user, the Admin who is someone in the US offices. And it’s been more than two years since anyone touched that code. As everyone suffers from tunnel vision, the Engineer simply could not see that the tweaked code is a very sensitive Business Logic shared by not two Products, but by another long forgotten Product. Again, a Non-Technical Cause and an correctly cohesive implementation. Things that will change together need to be together – but should they?
The answer is not that simple because Products are naturally intertwined, they share a common.
Actually, the answer is simpler than we might think. It’s only our binary thinking minds that prevent us from seeing it: some should Change together, some shouldn’t. As we strive towards separation, a negative phrasing would be more beneficial – what shouldn’t Change together, shouldn’t Change together. Unless we really really really need to.
Silo’s physical device (2020, manufacturing of a connected/smart vacuum sealer), had more than one experience. Besides its main intended use, there was the update experience, a customer experiencing a Flow. For him it was some audio/visual messages and a progress bar rendered on the LCD screen.
Only a small part of this Flow was the “actual update” that fetches the update from the servers and burns it to the device. Every little mistake in this update mechanism had the potential to brick the device, completely destroy it to the point it needs to be recalled into the factory. As it was expected to run concurrently on millions of devices at people’s homes, a failure in the update mechanism can have the potential to ruin the entire company.
As such, we’ve thought of every edge case, thoroughly planned for every failure imaginable and unimaginable, and of course thoroughly and repeatedly tested it. We’ve done our best to make it as robust as possible. Well, you know, as long as nobody Changes it without a proper Cause. What I was most terrified of was a future someone who would like to Change the experience and would also Change the update mechanism. With or without Intention.
This was to be prevented at all costs, so we wrote down a law for ourselves – the update mechanism and the update experience should not Change together. We drawed two clusters of Causes. One with Causes to Change the experience, another with Causes to Change the mechanism. We wished to enforce this mutual exclusivity against a future reality of someone who wishes to Cause a Change for them both together.
We did so by enforcing two Directions of Change with an unremovable stop sign. If there’s a Cause to Change the update mechanism, it can be done and it would be done via the left-to-right Direction and definitely not due to a Non-Technical Cause.
If someone, like a newcomer PM, wishes to Change the customer’s experience, an Engineer can easily go in the right-to-left Direction. What they won’t be able to do, even if the CEO wishes, is to Change the update mechanism. Even if they really wanted to. But if they really really really needed to, due to an imaginable Cause, they can refactor it. It would be a hard one that would make them think twice and make sure they really really really need to do so.
The technicalities of the resolution is beyond the scope of this series, it would be later discussed in the Breaking Change series. It is enough to say that we’ve kept the entire development of the update mechanism, from coding to deployment, completely isolated from everything else. And its deployment was kept manual, with a merging permission only to the company’s CTO, which was me.
We’ve learned of another way to not only discover Directions, but to create them within the Change Stream. Just by saying “shouldn’t Change together”, we forced ourselves to investigate our Causes and discover a mutual exclusivity within them. Which we should not forget to properly name and test them.
The above is not limited to Technical and Non-Technical Causes. It can be used within each one of them. For us, that would be applying it to our auction website: the Admin’s experience should not Change together with the Seller’s. And they both should not Change together with the Buyer’s.
Problem is, the Product Modules X,Y and Z are so independent that even if we really need to Change them together we can’t. And we need to because Products are intertwined and share commons. There is also a gap to bridge between the Technical Modules and the Product Modules, to code the relationship between them.
But Silo’s application was for a single Product, so that would supposedly entail a single Product Module. But the update experience itself has its own set of closed Causes. So there should be more than one Module. So how many Modules are there?
It seems like we are in some sort of a mess, but it is this very same mess that exactly shows why Product Modules are nothing like Technical Modules. On that, in the next chapter.