Kevin Delemme

Kevin Delemme

Senior Software Engineer @ Busbud

Domain Driven Design & Testing best practices


Abstract your domain from the outside world

April 22, 2020

Working with a legacy application, I tries to create new features as much as possible isolated from the legacy code. When you are in the same application, in a monolith, it is way too easy to just add code and use functions and other services from all over the place. After all, why not? We have access to it, it’s part of the same application. The problem with not respecting boundaries, is that your logic starts to be spread everywhere, and touching one part of the code has consequences on other parts.

Recently, I’ve tried to introduce some sort of bounded context that are isolated from the rest of the application. Concretely, it means that:

  • the outside world cannot access my domain models directly;
  • the inside world of my bounded context cannot access the outside world directly

Instead, if I need something from another bounded context (I considere the whole legacy app as one bounded context), I treat that like a third party service. So the thing I get back is transformed into something from my bounded context.

Here’s an illustration: example

My New Bounded Context™️ needs to use the User (or at least some part of it) that is defined in the Legacy App. So instead of simply fetching the User (from the db or whatenot) and using it as I would do in the Legacy App, I introduce a User domain model (that is different than the other User) of my New Bounded Context, and a UserClient with an implementation that takes care of:

  1. Fetching the Legacy App User
  2. Transforming the Legacy App User into the New Bounded Context User

And now, within my New Bounded Context, I have a brand new User that contains only the fields and methods that I care about in this context. The other advantage is that if someone decides to change the User of the Legacy App, it won’t affect my New Bounded Context

It can seem counter-productive and expensive to introduce an Anti-Corruption Layer when you are in the same application, but it makes you go faster in the long run since there is less coupling, changes are more isolated, and therefore safer to do.