by Leon Rosenshein

Don't Cross The Streams

Domain driven design is all about bounded contexts. I like bounded contexts. They help you know what something is responsible for, and by extension, what it's not (that would be everything else). Having those boundaries (not crossing the streams) makes it easier to keep things straight and reduces cognitive load.

On the other hand, having all those different domains is adding complexity, Especially if those domains are each different services with some kind of RPC interface. In that case you not only have multiple domains to keep track of, but you could do everything correct and the RPC could fail because of a fiber seeking backhoe, so you need to be able to handle that case. And that increases cognitive load too.

Like everything else in software, when to keep things separate and when to bring them together depends on context. Remember, we're not here to build the perfect thing, we're here to add value to the customer. Value today is better than undelivered perfection.

It's a balance, and the right place for the boundary will change over time. How often things change can move the boundary. The more something changes the more important it is to make it easy to change without impacting others. How many other people/teams/programs need to use the context can as well. If there are 100 use cases then having a single version is very important. If there's only one use then it's already used in every case.

There are sometimes good reasons to cross the streams (mix your domains). One of the most common is time. And that can be OK. As long as you document why you're choosing a short term gain over long term stability and what the criteria are that will tell you when you need to fix it. For example, you might mitigate an outage by crossing a domain barrier in a client rather than make a change to a few domains, because you need to fix it now. But once things are working and you have the time, go back and clean up the boundaries so everyone gets the benefits.