3

I recently decided to learn Domain Driven Design. I came up with a hypothetical application and tried designing the architecture for it. It is a simple Poing-Of-Sale application with bounded contexts Sales and Inventory. This is where I have two conflicting designs when implementing the code for these bounded contexts.

Design #1:

  • Anything and everything that has to do with inventory belongs in inventory bounded context.

  • If a sales order comes in, the request initially enters the sales bounded context, then one of the steps to make the sale, you must check the inventory to see if the item is available. In which case, you request the inventory context (however this is done within the system). Inventory context will check the database and respond back with availability confirmation. This way any other bounded contexts that need any kind of inventory involved logic would use this bounded context to achieve it. Code is encapsulated and good to go.

Design #2:

  • The division of bounded contexts are strictly at the business level divisions in their operational contexts.

  • If a sales order comes in and hits the sales bounded context, it should contain all the logic in code that has to do with sales. It would check the database whether an inventory is available via the service, it would then remove that item from the inventory, record the sales in database via the service again, send out an sales made notification email to admin if this is a requirement. Just everything and anything that has to do with sales will all happen in this bounded context. Once the sale is made, it could fire an event sale made, and inventory context would listen to this to check the inventory in the database, see if new purchases need to be made to bring in new inventory or not as it is an operation related to inventories at the business level.

I am just trying to understand what Domain Driven Design approach is in such system. Thanks.

=================================

After some thought this is the added question to the original.

Let's say your business needs to do shipping. Whether it would be due to making a sale (Sales Bounded Context) or due to a warranty replacement (Support Bounded Context). What if shipping itself is complicated depending on situations. Where certain products or shipping addresses you need to make the decision to ship it yourself or via some 3rd party shipping company using a web service. Does the "shipping" deserve its own Shipping Bounded Context? Or it simply is just another domain logic embedded in the Sales Bounded Context and the Support Bounded Context? This is all within the case of simple retail store domain.

jiminssy
  • 2,149
  • 6
  • 28
  • 45
  • 1
    Possible duplicate of [Communicating between two Bounded Contexts in DDD](http://stackoverflow.com/questions/16713041/communicating-between-two-bounded-contexts-in-ddd) – guillaume31 Oct 06 '15 at 09:44
  • 1
    I don't think it is duplicating because I am not just wondering about the referential data. In the case of my shipping question, I am trying to determine at which point does it make sense for you to have shipping as a separate context. Or does it even make sense to have separate context at all? As a business what exactly are you doing with just "shipping" that it becomes a "bounded" context? – jiminssy Oct 06 '15 at 13:45
  • 1
    Bounded Context is linked to the concept of subdomain. You have a subdomain when your organization has separate business processes and oftentimes a dedicated team for the functional area in question. See http://gorodinski.com/blog/2013/04/29/sub-domains-and-bounded-contexts-in-domain-driven-design-ddd/ http://www.jefclaes.be/2014/02/strategic-ddd-in-nutshell.html – guillaume31 Oct 06 '15 at 14:00
  • I suggest you ask a new question for this, since the original Q seemed to assume the presence of multiple BC's as a given. – guillaume31 Oct 06 '15 at 14:02
  • 1
    DDD is difficult to practice at home because you need business people. Without business people you won't be able to catch what is important or not. Moreover, stackoverflow does not always promote "feedbacks on experience". I suggest you to ask on google+ communities or linkedin to hear from real-life DDD practitioners. – Rénald Oct 06 '15 at 17:44

2 Answers2

2

My 2 cents... Design #2 seems better as Design #1 should lead you to a distributed system. You do not want a distributed system. You should not take storage or tables into account before getting the business. Just consider business, and when you get it, consider how you could be able to get your BC run in complete isolation (offline mode vs distributed mode). If data is missing, then consider using Domain Events to propagate this knowledge to your BC.

Rénald
  • 1,412
  • 12
  • 29
  • 1
    We are using web-services for cross-cutting and "sensible" domains, for instance for "Referential Data" that do not evolve. As these referentials do embed very static business rules, we do not apply DDD to these. Context is king. – Rénald Oct 05 '15 at 18:25
  • 2
    Then this "Referential Data" effectively becomes what is the "infrastructure" in DDD? And a service would provide interface to fetch these data. All these embedded static rules are completely hidden as service effectively becomes the interface. – jiminssy Oct 05 '15 at 18:28
  • 1
    That would be no different from having the service to fetch from your own database. Since the way I understand the services is that they are just interfaces at the infrastructure level. – jiminssy Oct 05 '15 at 18:35
  • 1
    At an enterprise level, it is for a more political reason in fact... As many members in the team were not very confortable with DDD and were feeling disappointed not implementing micro-services or REST, we defined this rule to make everybody happy... It works and it is quite logical. Our "Client Repository" and our "Financial Factory" are managed this way, the REST way, without Domain Events or replication (critical and static rules)... – Rénald Oct 05 '15 at 18:38
  • 1
    We are distributing only critical and administrated data, all data that are at a more daily business level are implemented through Domain Events. The agile way. – Rénald Oct 05 '15 at 18:44
  • One problem I see with my design #2 approach is that I could get into potential race condition. Let's say my Sales bounded context queries the database to fetch the item first for "whatever reason" and sees ok, i can sell this and remove it from the database upon "making the sale". But at the same time some other bounded context fetches the item to do its whatever logic to run diagnostics on it and decides to remove that item. We have effectively run into race condition. Should this be handled at the service level? – jiminssy Oct 05 '15 at 18:44
  • Handle I mean prevent fetching the item by locking if someone is taking a look at it? Or any other mechanism for that matter. But what I am saying is this is a concern of the infrastructure implementation level, not at the bounded context level which is a higher abstraction. – jiminssy Oct 05 '15 at 18:47
  • Yes, your domain is "eventually consistent". If your domain allows it, then there is no problem. As data is propagated through Domain Events, your model (data/behaviour) is consistent, even if it is not really up-to-date. – Rénald Oct 05 '15 at 18:50
  • In the case of removing the item from the database, it is more a transaction, not eventual. My sales bounded context fetches the item first but something else removed it from the database for some reason. So when my sales context tries to remove the item in the context of making a sale, and database service throws an exception, i guess at that point I would mark that sale as failed and reverse back. Eventually letting the customer know his purchase has failed. – jiminssy Oct 05 '15 at 18:55
  • Referential Data should be transparent. To avoid Race conditions you should implement "Referential Transparency" when processing Domain logic... – Rénald Oct 05 '15 at 18:56
  • This is why Referential Data fit so well with web-services... – Rénald Oct 05 '15 at 18:58
  • I am not quite understanding the "Referential Transparency". Could you give an insight with my specific example. In the case of making a sale and the database. – jiminssy Oct 05 '15 at 19:01
  • Load Referential Data for the current scope - Process Domain Logic without getting back to the web-service until your unit-of-work is done. – Rénald Oct 05 '15 at 19:06
  • @Rénald I'm not sure why option 1 would systematically qualify as a distributed system. You can have a different Bounded Context running as part of the same process, right ? – guillaume31 Oct 06 '15 at 09:27
  • You're right, it would not systematically qualify a distributed system. But for someone who asks for learning (maybe at home) I think it is good to stay on nominal cases. My alert concerns the data-driven approach Option #1 seems to promote. According to my experience (in the company I work in), this kind of approach frequently leads to micro-services... many developers think they are doing DDD when they implement micro-services (infrastructure driven bounded contexts, like tables...), without taking care of handling the business in a top-down approach. This is my daily fight for DDD. – Rénald Oct 07 '15 at 09:36
0

Design #1 is the correct one. Inventory context should be the only one which decides and knows how to check for inventory. It could be the inventory context is checking from multiple places and those could be changing based on meta data updates as new data warehouses come online. At some point retailer might decide to have all physical shops as data warehouses as well.

Similarly shipping should be a context as well. Notes above said we should not aim for distributed system but I don't see why not if that provides agility.