0

Scenario

I have a Customer and a CustomerSettings object. When I create a customer I also need to create their CustomerSettings object. These settings can dictate the customer experience immediately following Customer creation. After the CustomerSettings have been created there appears to be no reason for synchronization between the CustomerSettings and Customer entities - other than deletion, Alice can make changes to CustomerSettings while Bob makes changes to the related Customer. When a Customer is deleted, the CustomerSettings must also be deleted (although this could happen eventually after successful deletion of the Customer).

Question

Should the CustomerSettings be part of the Customer aggregate?

Additional Thoughts

If I follow the first rule of Aggregate design

"Protect business invariants inside Aggregate boundaries"

it would seem that the CustomerSettings entity should indeed be part of the Customer aggregate because the CustomerSettings object should be created when the Customer is created. It seems somewhat unreasonable, however, as only the creation of these two objects needs to be transactionally consistent.

  • It might help to give some further description of what CustomerSettings contains, in order to clarify the actual relation between Customer and CustomerSettings, so that you can get a more targeted answer. Maybe CustomerSettings is not really a relevant Domain object at all, in which case it probably ought to be created and held somewhere outside the Customer, or it may be an alias for something truly relevant to the Customer. In any case, this is not entirely clear right now. – Vector Zita Sep 16 at 20:18
  • let's say these settings could be composed of notification preferences (which notifications they want and if they want them by email and/or mobile) and theme settings (dark vs light theme) – Jordan Sep 16 at 20:20
2

Well, it depends on where you draw the "boundaries" of your Domain and how flexible you want to be with respect to serving various use cases. In any case, the fact that the objects share their lifetimes does not necessarily mean they are better aggregated together.

It looks like your CustomerSettings object is not really a Domain-related entity, in the sense that it does not represent an actual entity, nor is it related to the Customer outside the specific use case. It appears to exist only because the Customer is the subject of a specific service, which appears to relate to preferences with respect to a notification system, the appearance of a "front end"-like interface etc. and you need a place to persist service-specific preferences.

Consider the concept of a Customer, instead. If, along the course of the evolution of your design, another service comes up, which requires different types of settings, for example a crediting system, where customers choose how to manage their credit. Do you create a new CustomerCreditSettings object inside the aggregate root?

What I am trying to say is that if you want a Customer object to serve different purposes, and potentially persist Customer objects to a database, it makes sense to only persist what is congruent to the Domain, i.e. your Customers. Whether the database is used by one service or another, which have different needs, expose different capabilities/features and, as a result, require the additional persistence of different "settings", should not matter at all to the Customer object, i.e. you do not make special provisions in your Domain representation just to serve a specific use case. All that because if you incorporate your "Settings" inside the Customer for services that depend on Customers, whenever you are asked to serve an additional use case, you will have to change your basic underlying implementation and this is not a very maintainable solution.

In short, the settings you are referring to (and any related objects not directly contained within the Domain) are probably best used decoupled from the Customer object (in fact, the Customer object can be completely ignorant with respect to them). These can probably be better represented by a map between Customer and CustomerSettings objects, and an observation of corresponding domain events of Customer insertion/removal, which is to be followed by, among other things, a creation/deletion of the corresponding CustomerSettings object, somewhere close to the service. You could take care of CustomerSettings persistence by, potentially, linking it to some unique Customer ID when outside the boundaries of your Object-Oriented Model (i.e. somewhere in "permanent storage world").

  • I agree. The settings should probably not be called UserSettings, but NotificationSettings. They should live in a different Bounded Context. – Rik D Sep 17 at 5:25
  • I agree with something more like NotificationSettings or more specifically CustomerNotificationSettings but as these settings are specific to the Customer I'm not sure they belong in a different bounded context – Jordan Sep 18 at 12:25

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.