Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
How do you get junior developers or someone new up and being productive within your system? Never mind domain knowledge. There is a lot of technical tribal knowledge about how you handle logging, persistence, validation, and various patterns and practices you apply within your specific systems architecture. Here’s how I think about it by creating silos.
Check out my YouTube channel, where I post all kinds of content accompanying my posts, including this video showing everything in this post.
In a simplistic view, you might think you have a web application or HTTP API with a controller that invokes a service layer that interacts with your database.
You could think of A and B as types, layers, components, whatever. The point is they illustrate the coupling between them.
In reality, however, it’s not a single usage. Typically, you will have a high degree of coupling to some type/layers, etc.
This is typical when you have some abstraction or layer around data access. Yes A is coupled to B, but at a very high degree, making “B” more fragile to change. If you introduce a bug or non-backward compatible change to “B”, it can affect many different usages from A.
Check out my post, Write Stable Code using Coupling Metrics, as I’m describing Afferent and Efferent coupling.
Another common situation is having a lot of indirection where a request goes through various layers and types.
Pile on top of that a high degree of coupling, and you’re in a system that will be hard to change.
If you’re a junior or someone new on a team, you’ll likely feel overwhelmed by the number of places you need to make changes to (layers) or will be so afraid of making a change because you don’t know the implications.
What often happens to combat this is developers will look at existing functionality and how it’s implemented. They then will re-create the same type of changes throughout various layers or piggyback off another feature, which ultimately conflates different features.
You want to be working in isolation. You want someone new on your team or junior developers to have the freedom to work in isolation without having to worry about every part of the system. To do that, you need to manage coupling. You want to be able to add functionality to your system without affecting any other part of your system. I like to think of this as working in silos.
A silo is independent and oftentimes will resemble other silos.
Their structure is the same. However, internally what they implement can be different. This makes them great for being a template to kick off a new feature. The template will show all the different patterns, practices, and tools you use to start quickly. Think of it as scaffolding a new feature.
This allows new people on your team to instead of piggybacking on existing features or having to change and touch code through different layers, they can create their changes in isolation. You’re minimizing coupling as much as you can.
This means that one silo won’t affect another. Because you aren’t coupled between them. The best way to illustrate this is with the publish-subscribe pattern.
In an e-commerce system, you publish an OrderPlaced event when an order is placed. You then can have 0 or many different consumers of that OrderPlaced event.
In the example above, there are two consumers. One is for sending out a confirmation email, and another consumer is used for sending HTTP requests to other systems as a webhooks system.
They are independent and have no coupling between them. This means we can add a new consumer at any time, completely independent of the other consumers.
This is the type of independence you’re after. However, not everything is going to be decoupled by the publish-subscribe pattern, but the intent is still the same: limit coupling.
Silos may share some common concerns. For example, they may share the same underlying data model, but they likely don’t all work on the same data. Or if they do, you’ll likely share a domain model in that case.
They aren’t share nothing. You will have s some cross-cutting concerns, but generally, those are more technical concerns rather than business concerns (excluding a domain model).
Because there’s limited coupling, this means you can add silos and remove silos without affecting others, similar to the illustrating with publish-subscriber consumers.
Ultimately this makes your system extensible. You can leverage templates that illustrate the common structure but need the implementation details created. Every team has various coding standards, how they use certain libraries, frameworks, and tools. This allows you to define those and have the focus simply be on the implementation of the functionality required.
You might be thinking, “Are you just describing vertical slice architecture?”. Yes, to a degree. Vertical slices are a great way to think about silos. Meaning a feature or a feature set is a silo. It’s also helpful to think about CQRS in accomplishing this as well. However, the end goal is controlling coupling. You’re junior developers (and everyone on your team) will thank you.
Developer-level members of my Patreon or YouTube channel get access to a private Discord server to chat with other developers about Software Architecture and Design and access to source code for any working demo application I post on my blog or YouTube. Check out my Patreon or YouTube Membership for more info.
- Write Stable Code using Coupling Metrics
- Vertical Slice Architecture, not Layers!
- Highly COHESIVE Software Design to tame Complexity
- Distributed domain-driven design, a no-nonsense implementation guide