- Damian Płaza
Imagine there's a small (really, really small) organization that give consultancy services related to accounting and warehousing.
Accounting advisory is a bit special because it uses simulation methods to increase the value from the service.
Three-Man-Army needed to organize themselves to work toward same goal - that's what organizations do, right? (what am I talking about? If you're curious, please check "Organization-Driven Design")
Let's introduce the crew!
Tom, The Accounting Expert - doing the majority of the services.
Theo, The Simulation Expert - bravely assisting Tom.
And finally Tony, The Warehousing Expert - quite independent.
As we now know our heroes, let's move on!
Tonydoes his work separately, so he doesn't need anything from either Tomor Theo.
Things look a bit differently for other two.
Tomand Theoare closely collaborating. Any time Tomhas any work related to accounting consultancy, he needs to ask Theoto provide him some simulations.
Theois actually very independent - he doesn't require anything from either Tomor Tony.
One could ask - is everything fine?
Our little team works together so they need to rent some office space.
Let's imagine that the market is a bit turbulent and they are changing their office location multiple times.
We're start with their first setup - a single room.
Typically, people are talking to each other to do their jobs, aren't they? (hopefully!)
Pushing our imagination further, let's simulate that Tomand Tonyhad a little discussion, during their lunch break (Theo wasn't around).
Seems like everything is fine, isn't it?
The new office
Due to various reasons, guys needed to distribute themselves across the office space.
Tomand Tonystayed in the same room, whereas Theowent into another office room - but still in the same office building.
So now, our little team occupies two rooms.
As previously, Tomand Tonyhad a little discussion.
Guys delivered the value and customers were happy, although they sometimes gots feedback about slower response times.
Tompromised that things get better when they properly settle in their new office, as they changed places.
Opinions like "It isn't that bad" made Tompretty confident.
Again, things got a bit complicated. Big Corp'n'Slash came and offered higher price than our little heroes.
As they knew each other quite well, they decided to do the split - Theowas the one who said he could move to another office building
He was pretty independent, he didn't need anything from the rest of the crew.
A great division happened.
There was a physical distance between buildings, are they were located in the different parts of the city.
"We are living in the internet era, no worries", Theosaid.
Yet again, there was a tiny discussion between Tomand Tony.
Well, things are much more serious now. Tomis flooded with really not the best feedback about their services.
What previously took 3 minutes, now might take 10 minutes. And what's worse - sometimes he can't answer to the customer's request.
Theoseems unavailable. Probably, due to the internet connection issues.
So apparently their delivered value is diminishing. Why?
Knowledge, needs and collaboration
What the hell just happened? (you asked this question, did you?)
We saw the same topology of people, having their own duties and responsibilities, in three different scenarios.
There were interactions, communication and knowledge needed to deliver their services.
But something started happening when both Tomand Theowere getting physically separated.
Greater the distance, harder it was to deliver the value by their joint effort.
Closer the distance, harder it was to see "the potential bottleneck".
Heisenberg's uncertainty principle?
Let's change a topic, for a while.
Have you heared about Werner Heisenberg? He formulated a very well-known principle that states:
Position and momentum of an electron cannot be determined simultaneously with absolute accuracy.
It can be expressed mathematically as follows:
Equations are daunting (are they?), but what might it mean?
From the helicopter view it might mean one thing - a trade-off.
You cannot get two things at the same time - "pick your own poison", one could say.
Either you get this or that. No free lunch.
Why am I bringing Mr. Heisenberg and his novel observation?
Our systems are not throwing modularization exception or they don't produce compile-time modularization errors.
That's a trait, a characteristic, we can experience directly (or indirectly).
It is well-known fact (not my invention) that systems are subjects of an unspoken ying-yang of software engineering: coupling and cohesion (ying-yang? I am giving an explanation in Software Engineering for busy parents).
Low coupling and high cohesion looks like a holy grail of modularity heaven.
But how to define them? You probably know that I like definitions and semantics. Also, I don't want to invent any sophisticated explanation.
I also like metaphores and analogies, so the best would be to use a metaphor.
As our little tale is about people, organization and effective communication - let's use communication as a mean for describing them.
Talk your collaborators
Tomrequires knowledge from Theoand in order to do this job, he needs to talk to Theo.
We could say that in order to deliver the value, Tomdepends on Theo.
But Tonydoesn't need anything from either Tomor Theo.
Then, a necessity of communication between peers can be expressed through coupling.
Shouldn't we aim at "loose coupling"?
But what about cohesion?
Be close to your friends
We already noticed that Tomdepends on Theo. They need to have a chat to satisfy their service and fulfill the contract with the customer.
As they need to talk very often, it makes sense to keep themselves close to each other.
What would happen when Theowould change format of his simulations, still being in the same room?
He would probably just mention that to Tomand they will adapt quite quickly.
But when they would sit in different rooms? Different buildings?
They would need to have a Zoom or Teams call, exchange much more words and sounds to eventually agree on the changes.
Keeping teammates and collaborators together can be expressed through cohesion.
In our little tale, high coupling between Tomand Theowasn't visible and wasn't problematic as we "increased" the distance between them.
In other words, as we decreased the cohesion of the system, we made coupling much more visible (and painful).
By decreasing cohesion, we made fixing the problem with coupling much harder.
It would be the best to keep highly dependent collaborators close to each other.
I can hear you (was it you?) - "but what if we can't keep them together?"
Possibly, when we need to separate the highly coupled collaborators, would it be an idea to reassign the responsibilities?
Could Tomlearn how to run simulations, when Theowas far away?
Modularity Uncertainty Heuristic
It might seem difficult to observe high coupling when collaborators are close to each other - but when we notice it, it's quite easy to "fix" the problem of responsibility reassignment.
On the other hand, when coupled collaborators are far from each other, it's quite easy to observe this high coupling - but it's difficult to reassign the responsibilities.
It has similar nature as Heisenberg's Uncertainty Principle has - duality of mutually exclusive actions.
(Re)Assigning responsibilities and noticing the high coupling in a system cannot be applied simultaneously with absolute ease
In other words, it's challenging to change responsibilities when coupled collaborators are distributed throughout the code or throughout services - but it's quite easy to notice it.
Contradictory, it's challanging to observe high coupling between collaborators when they are close in the code or inside of a service - but it's quite easy to change responsibilties.
What does it mean to us?
Don't be hasty with distributing the responsibilities - Slow down, observe which collaborators are affected by the changes - when things settle, consider separation.
"But what does it mean, practically?", you might wonder.
It's quite popular in the .NET world to keep each related classes, interfaces, enums in separate files. This means low cohesion.
If a change in each subpart requires touching other subparts - it starts being a bit thorny. What if they are very distributed across codebase?
Keeping controllers, models, services, abstractions, repositories, dtos together, by their kind or technical functionality - this might get pretty painful.
A remedy would be - start small - everything in a single file. Slow down. Let the organization thrive and grow. When it's too much, distribute the responsibilities. (what am I talking about? Please check Microoffices" vs "Officeolith")
Coupling and cohesion aren't only the qualities of the code - they are qualities of systems. As we orgnize our code, code organization also forms a system. Think about that.
I command you to learn by heart the Modularity Uncertainty Heuristic. Tomorrow you have an exam.
Exaggerating, like always.
How it can help us in our daily job?
Before deciding to "reuse" something, wait, sense and experience to justify this common responsiblity. Watch the collaborators, check if peers are close to themselves.
There are statistical tools and approaches like Behavioral Code Analysis that might work as a companion to old tools - discipline, analysis and awareness.
To not leave you, dear Reader, with nothing, here are the brainteasers:
- in the context of the architecture, what does "physical distance" mean?
- in the context of the code, what does "physical distance" mean?
- in the context of the architecture, what does an "office room" mean?
- in the context of the code, what does an "office room" mean?
- is it inherently bad for highly dependent collaborators to be far from each other?