18

I've been working in a relatively complex application with 10's of database tables (Aggregates, Entities/Value Objects) and applying DDD. At this point it appears to be basically DDD-Lite meaning that there are Application/Domain Services, the Domain Model (Entities, Value Objects), and Repositories.

I picked up a book Implementing DDD and the first thing he is mentioning is DDD-Lite and Bounded Contexts and Domain Events missing as first mistakes which are usual when beginning DDD.

Currently I've tried organizing the Domain Model by Aggregate relationships, and using namespaces to demonstrate it.

I'm failing to see the benefit/downfalls relating to separating the Domain Model project into separate Bounded contexts (yet). Perhaps it will become apparent later on but I'd like some real life feedback on Bounded Contexts (and possibly sub domains etc. if they tie into it).

2
  • It seems to me that the only thing defining separate bounded contexts is the need to differentiate linguistics and associated operational differences, i.e. it's called product in one area and product in another area but they are different, so we need two products and they both can't be in the same model (same name etc). So why don't we just change the names to represent their subtly different semantics? They we could have one model to rule them all. Subdomains are natural but I am not seeing bounded contexts at the moment. Just thinking aloud here... Sep 26, 2016 at 10:23
  • I guess you already realized why it is profitable to split your domain on contexts. So what could be useful now is the right way to identify them, to define the context's boundaries. Here is how I do it: medium.com/@wrong.about/… Dec 2, 2017 at 18:36

2 Answers 2

22

Consider a company that has a few different departments:

  • Software Development
  • HR
  • Accounting

Can you come up with a user model that can expressively represent all those areas of business? Think of what the User entity could look like in each one. Perhaps it's split into three different entities:

  • Developer
  • Employee
  • Payee

The effort to instantiate a user in each context is considerably different. Perhaps it's something like this:

  • new Employee(ssn, name, joindate, dateofbirth, gender)
  • new Developer(Employee, workstation, credentials)
  • new Payee(Employee, role)

excuse the example, it's hard to illustrate accurately without a proper domain model to reference

If you used a naive implementation and used a single user entity, it would end up being an anaemic data model full of getters and setters, because you couldn't fully represent the user all over the place.

There are clear boundaries in the business, so it's useful to model them that way. A user logging in versus a user in a payroll system versus a user playing a game are all very different, even if they are part of the same grand system.

Thinking in another way - you can now create your developer management code to be very lightweight and independent from the rest of your system. It can use more accurate types with less baggage to worry about. It's the step to building smaller subsystems that may eventually be extracted out into its own application.

5
  • Thanks for the supporting example which helps illustrate the different needs of the 3 BC's.
    – lko
    Oct 4, 2013 at 18:21
  • Not the way I am used to seeing these concepts: normally, an Employee is not a User, it has a User. The User is simply an entity through which a person can log in and access one or more applications inside the organization. And an Employee does not always have a User. Also, you normally don't get a simple application for different departments; typically, each department has its own apps, each containing its own domain model(s). So, to me this answer does not help clarify the need to have separate bounded contexts in the same codebase.
    – Rogério
    Jul 12, 2015 at 21:43
  • @Rogério your objection is actually a beautiful example on why it is important to properly define the ubiquitous languages used inside every bounded context :)
    – MauganRa
    May 18, 2017 at 19:36
  • I just wonder in the cases when we have a customer management system, when we phone to query our orders, or billing, etc. we get put on hold whilst we get transferred to the appropriate department. The domain knowledge of each department comes into play - much to the annoyance of the customer in these scenarios. Maybe we can blame DDD for forcing the separation between these contexts.
    – Andez
    Oct 30, 2017 at 9:46
  • So in a music streaming system, a User (in the account management subdomain) is a say Listener in the core domain (with different data and behavior). Is that correct? If so, how should I design the repositories for database access and manipulation? Dec 10, 2020 at 8:53
18

I can give you another example. Consider you have some ecommerce system. You would have products there, however products will be part of at least two different domains:

  • Product catalog, where you keep your product description and all attributes
  • Inventory, where you have product stock level

If you have one bounded context for both domains, your solution can quickly become a big ball of mud because you will start cross referencing it. At the end you will not have two domains anymore. Your product inventory will be spoiled with product catalog references and vice versa. As the result of this you will not be able to change one domain without touching another even you fully realize this is not required. Your models become dependant on each other and tightly coupled, and dependant in a bad way - being dependant on implementation.

If you, however, have two bounded context, all changes you do in one domain will not affect the other as soon as you keep your communication channels clear. It will mean you need to have data duplication but this is the least cost to pay for losely coupled component based application. Your domains can talk to each other using domain events. Even if you do not plan to have SOA based application in the beginning you will be able to scale up to that level when you need with relatively low effort since you just change the transport for your domain events, leaving the idea behind it intact.

Update: There is a good skillscast on SkillsMatter, from Eric Evans. He gives an analogy of the old story, when several blind man describe an elephant from their perspective. Since each man can only touch a part of the elephant, they describe it as a "tree", "wall", "snake", "rope". And each of those man is right within their context. Bounded context is where ubiquitous language lives. Outside the context, these terms might have completely different meaning but inside the context, the language is the same across multiple domains. Greg Young strongly suggests to start reading the blue book from chapter 11, since the most important, fundamental concepts are explained there. The focus on tactical patterns in the beginning of the book makes this "DDD-light" approach very common, when people stop reading somewhere around chapter 8 and miss the main things, that is somewhat buried at the second half.

4
  • 3
    +1 for also bringing up the duplication. it's a little confusing at first ("Am I doing this wrong?!) but it's completely natural, any in many cases, required. Oct 8, 2013 at 21:56
  • In this scenario are these Product classes both hypothetically sharing the same ID (e.g. both of the separate BC tables have a foreign key to a table with a single Product ID)? Perhaps when communicating with Domain Events they could use that ID?
    – lko
    Oct 9, 2013 at 17:55
  • 1
    It all depends on what storage is chosen. It is not necessary to use the technical id to refer cross-domain. It is also not advisable to make cross-context communication. Sep 30, 2014 at 17:21
  • 1
    Looks like it's time to get the blue book out of the shelf and read those later chapters Jun 14, 2016 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.