0

Good day, Please help me solve the dilemma. I am trying to write an e-commerce engine relying on DDD.

Problems associated with two aggregates, ProductType, and Product. Product is a classic product like in any other system with the exception that it can have a different set of additional properties. Features and composition of properties determined by ProductType which in turn refers Product i.e. Product have an id of ProductType. The Product can have ProductType or not it means that it can have additional properties or not like size, width, height. Properties may be bool or just string or list of options and they can all be required or not. All this knowledge about the composition of the properties and their validation contains ProductType, Product contains only concrete values for this properties. ProductType is created on a separate page and stored in a separate transaction and also could be assigned to multiple products in the product edit page. The Product may exist separately from ProductType and ProductType, in turn, may exist separately from Product. I.E. behave like two independent aggregates.

and now the question

When I save the Product with assigned ProductType and values according to ProductType properties I need to validate all of these values according to the rules in ProductType. How to ensure transactional consistency (in terms of DDD) saving Product knowing that ProductType could be changed by separate users in separate transactions ?

  • some pseudocode of Product and ProductType would help, it's not very clear what exactly the problem is – KolA Aug 22 '19 at 20:00
  • @KolA, Currently there is no final code, it is like mental model ), Maybe I'm wrong with this model. Maybe there is some more suitable model design ? I hope the main goal are clear. – cephei Aug 22 '19 at 21:11
  • "Maybe I'm wrong with this model" - it's possible; one of the purposes of aggregates is to keep things consistent within the boundary, another is to keep inter-aggregate dependencies under control. So if your aggregates need to talk to each other too much, or if there are rules that span aggregates but cannot be made eventually consistent, then maybe your current design isn't reflecting the actual interactions between the objects. Try partitioning code into aggregates differently, by drawing boundaries around groups of objects that interact most closely - then give those concepts a name. – Filip Milovanović Aug 23 '19 at 0:18
  • @FilipMilovanovic Yes agree, Could you put forward yours visions and solutions regarding model ? – cephei Aug 24 '19 at 10:43
0

Flip the problem.

The ProductType aggregate knows the details of Product aggregate since the product's structure is governed by it. Instead of trying to create a product with a ProductType parameter, invoke a method on ProductType to create a new product instance. In other words, the factory method to create a new product will be part of ProductType.

Not only will your Product initialization become more natural, but the parameters that you pass into the factory method can be validated immediately.

A thumb rule of creating aggregates is that each transaction/operation touches only one aggregate. In this case, you would only be initializing and persisting Product aggregate. Also, this behavior is not a violation of other DDD aggregate rules because of the close conceptual linkage between ProductType and Product.

As an example, I encountered a similar problem some time ago with Tenant and User aggregates. A User instance can only be created within a Tenant, but I cannot enclose the User concept within Tenant aggregate because the linkage is only during creation. Once the user is created, it is accessible and modifiable directly.

Also, I read your last statement as saying ProductType can be edited independently, and you want to verify that all Product instances confirm to the changed ProductType. I would suggest that you not do this, and treat the Product to conform to a specific version of the ProductType.

If you cannot do this and you really want to maintain conformity, you will need to fire a Domain Event when the ProductType is changed and write subscribers to pick the event and run validations against Product instances, as a background job.

  • Thank you, it is quite interesting idea. But what about Product life cycle ? every time when it will be decided to change product set of properties new Product will be created with new Id. What about users and links to specific Product, they will be lost ? "ProductType can be edited independently", it is a good point, my fail, i did not cover this aspect. In this case I decided not allow edit ProductType when at least one Product refer to ProductType. – cephei Aug 24 '19 at 10:35
  • Not sure I understand. Once the product is created, what prevents you from modifying the product directly? Do you need to refer to ProductType for every edit? Why would you need a new product when you change properties? – Subhash Bhushan Aug 24 '19 at 15:42
  • From time to time it need to update properties data and each time when we update it we need to check specific rules which only knows ProductType so we need to reference the ProductType, this is first point, second when we decided to change ProductType (another set of properties) related to the Product, based on your version I will be forced to created new Product due to the ProductType (factory) was changed. – cephei Aug 24 '19 at 18:10
  • Ok, understanding better now. A couple more questions: 1. ProductType has a few business rules that are referred to whenever a Product is changed. Is that correct? 2. If you change business rules in the Product Type, you want them to become applicable to all Products connected to the Product Type. Is that correct? – Subhash Bhushan Aug 24 '19 at 20:53
  • 1. yes, right. Rules whenever Product is changed and added new. For example some properties of set must be required or if property is list of options then check that selected value fit one of the options list and so on. 2. In this case I decided to prevent any changes in ProducType (rules or composition) if at least one Product refer to the ProducType. But in my original post I described situation when In the same time existing ProducType without any Product references being changed along with this same ProducType trying to apply to the Product (non-repeatable reads). Thank you. – cephei Aug 25 '19 at 0:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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