🦴 The skeletons in your architecture caused by needless coupling
A halloween special 🎃 Inspired by our live stream
Coupling and connascence are two words that everyone struggles with. You may have stumbled upon various principles like DRY and SOLID that give you rules and a gamified framework to follow to introduce better coupling.
But do you truly understand it? I picked a picture of a human leg. Were you to decouple all details, it would serve no purpose, no function other than being presented in a museum.
Then again, glue all the pieces together and you get the same problem. So in a way, bones in our body need to be coupled together to some degree that isn’t touching, without being separated.
Software coupling displays the same characteristics.
Sponsor: Pragmatic Clean Architecture (C#)
Jump straight into the tactics of Clean Architecture for C# engineer.
Crafting Tech Teams is an affiliate for the course above. Use the code DENIS for 10% off! Thank you for the sponsorship, Milan 🤝
Loose = weakly joined
A cable is a good example of two appliances that are weakly joined—or loosely coupled. Don’t you hate when you need a specific cable for a specific version of hardware that only works on a specific voltage? I’m looking at you, Apple.
Does Apple benefit from having specialised cables? Absolutely. Does it make upgrading harder? Also, absolutely. But you see—Apple benefits financial from this difficulty. Your software architecture doesn’t. Disclaimer: I’m happy to use Apple products.
There are three scales of elements in your software that require joining. The elements themselves can be architectural in nature, service-scale or simply two functions of code.
The mechanisms for loose coupling differ in what dimension is being made weaker:
Identity (or reference) axis
Value (or format) axis
Time axis
Execution (or platform) axis
These four overlap with the four forms of autonomy in distributed systems, as well as the four worst kinds of dynamic coupling mentioned in the theory of connascence:
Connascence of Identity refers to requiring the exact reference to the subsystem. This may be referring to a server by it’s hardcoded name or IP address or requiring a reference to an exact ORM-driven entity object in memory.
Connascence of Value refers to being coupled to the exact format that data values are being carried through. Does your entity and its fields change if you query it from MySQL vs Postrgres? Can you make a call to another service without coupling to HTTP or RabbitMQ transport protocols at point of calling?
Connascence of Timing captures the async vs. sync debate. Can you call a function in a way that allows it to retry now or later? Do you require responses in your requests in a manner that couples error handling? A service is coupled to another by timing if it cannot operate independently of its collaborator's downtime—even temporarily.
Connascence of Execution order refers to knowing intricate details about how the runtime works. This correlates with platform-level autonomy. A mock where you infer two or three exact calls to a integrating service is coupled strongly in this manner. State-based systems where replay of handshakes is necessary over the network are coupled like this: OAuth, SSL/TLS handshakes—these are coupling mechanisms that make testing and development isolation needlessly difficult.
DORA Dev Report 2023: Loosely coupled architecture is a productivity boost—But why?
It’s not what you think. The loosely coupled doesn’t have anything to do with hardware or machines. No, it’s exactly in the opposite end of the spectrum. Loosely coupled architecture allows your team to be loosely coupled from other parts of your organisation.
Hello, Mr. Conway. Quote from the 2023 report below (emphasis mine).
Loosely coupled teams, or perhaps teams that have loosely coupled architecture, are able to make significant changes to their systems without involving other teams. This enables teams to move faster. When subject-matter experts are closer to the team, they can review code faster because they have a better understanding of the impact of the changes. A loosely coupled design enables the team to test, build, and deploy without other teams being a potential bottleneck.
There’s nothing worse than investing heavily into a beautiful gantt chart only to realise all teams and projects are coupled together in a singular, slow stream.
What’s next?
If you haven’t already, I suggest grab a copy of the DORA DevOps report 2023. Adrian Stanek and I had a 2-hour stream on this topic last week with interactive, hands-on questions from a large live audience. You can watch the replay with live chat on Linkedin, Youtube and Spotify.
Later this week I will post on strategies for cleaning and decoupling a big-ball-of-mud / monolith, the cost efficiency of such projects and how to practice prevention.
Refactoring and architecture are the primary activity that more-experienced developers do on a weekly basis and report not having enough time for. The Thursday stream will cover estimation and #noestimation in greater detail.
Loosely coupled architecture may be achieved by event-driven architecture which, in my opinion works very very well