Domain-Driven Design – How to Clearly Define Boundaries of a Bounded Context

design-patternsdomain-driven-designobject-oriented-design

After a month or so of reading and researching DDD, I decided to start my own project and created DDD with these bounded contexts>

  • Clients
  • Products
  • Orders
  • Billing

Each bounded context has rest API as a presentation layer, domain layer, persistent layer.

So far so good, code is running smooth, but coming from a monolithic world, I am still trying to figure out the following:

  • when I want to create a new client, issue new invoice, create new order I want to for example access list of countries. Do I:

a) create a list of countries in each BC

b) create a Countries BC -> API and use it to get a list of available countries

c) use a 3rd party API and pull data via anticoruption layer in each BC

  • when integrating with 3rd party API using an anti-coruption layer or an adapter layer, what data has to be included in my domain model? For example if I want to integrate a zendesk API with a Client BC. Do I need just a ticketID in my domain, or I have to extract all the data from Zendesk that I want to access and use in a Client BC?

If my MVC app is actually getting data from APIs (presentation layers of my bounded contexts) I find it very difficult to clearly define boundaries of each BC. Does it mean that a properly designed BC would serve a single MVC controller without a need to consume additional APIs?

Best Answer

If your different bounded contexts understand the meaning/purpose of a country differently, then you need to model it appropriately different in each one. However, if we are speaking simply of reference data of ISO codes and names, then I believe it's pretty fair and standard to stash it wherever is convenient and make it accessible to all interested parties. For example: a database, a configuration file, a web service, etc.

I also wanted to look at your model a little bit. The pieces you have listed could very well be "entities" in one "bounded context", depending on the company's structure. BCs often end up being defined around different areas/departments/teams, since that's frequently the natural boundary between "ubiquitous language"s. So for example, instead of Sales/Products/Orders I'd expect the BCs to be along the lines of Sales/Manufacturing/Warehousing.

Inside those BCs, you don't focus on the nouns. You focus on the use cases, and create models of the nouns that can fulfill the use cases. The methods on an "aggregate root" execute use cases and make the appropriate changes to the related models.

... all models are wrong, but some are useful.

Also bear in mind that each BC may use an entirely different system or architecture. A given BC may not merit using "DDD software components" at all, and most of them probably don't. DDD is less about prescriptive software components and more about the process of designing software. The point is to focus on understanding the company's bounded contexts, mapping out each context's ubiquitous languages, and modeling the code for that context using their ubiquitous language. That way when you interact with stake holders and refer to the code, it sounds to them like you are speaking in business terms they understand. And recognizing that the same word has different meanings in different BCs.

There are specific patterns brought forth by DDD (e.g. repository, specific layering, etc.) that are means to an end. But these patterns are not guaranteed to be the best patterns for every case, even within DDD. Just like DDD is not "the" answer for every project. You just have to do what your analysis suggests is the most practical thing to do.

Related Topic