Gap between updated domain model and previously saved data

51 Views Asked by At

Assumption:

  1. Using domain driven design approach.
  2. Domain Model class holds business logic.
  3. Domain Model data is saved in repository.
  4. When tring to get the data from application layer, db data is first retrieved and the domain model class is instantiated with it, then the instance is returned to application layer.

Example:

  1. User domain model class has a property 'name' which has a rule: the length should be more than 3 and within 100.
  2. The class is instantiated with the 'name' property's length being 99 and the instance is saved in repository. The user's name is assured to comply with the rule.
  3. When application layer demands the user's data, it calls the repository method which returns the user domain class instance.

Now I'm wondering the case where the rule has to be changed: max length is 80. Then the repository method starts to throw an error(length of the user's name saved in db is 99, though the rule now says it should be 80 at maximum)

This 'name' example can expand to a more generic case: How can we get data from application layer when the domain rule is changed to a more strict one?

I've researched this topic but failed to find a best practice from a DDD point of view. Does anyone have a solution or experience with this problem?

1

There are 1 best solutions below

0
Levi Ramsey On

The root of the problem is that a domain rule can't change the past (it can change how the past is interpreted, but that's something different), because in the real world (which is hopefully what you're trying to model), you can't change the past.

This means that you can't reject entities which were persisted under earlier rules: the most you can do is model that they no longer comply with the current rules. This might in turn imply that there's an automatic reconciliation which could be done to bring them in compliance, but it could also just mean mark them as an older version and manually figure out what to do.

This may mean that modeling domain rules at a type level in your programming language is undesirable, unless, perhaps, you adopt a versioning scheme in the types (e.g. AggregateV1, AggregateV2, etc. which are considered different manifestations of the same type (you might use interface inheritance for this if your language supports it, otherwise adapters ("type classes" for you static FP folks in the back) are generally viable for this): "making the illegal unrepresentable" doesn't work well with persistence and changing laws.

In the case where the maximum length of the name property changes from 99 to 80, you might instead implement that as "it's impossible to modify the name property such that it's resulting length is more than 80 characters", but not change the type in your encoding of the domain class (nor change the DB schema...). You might implement truncate (or some other heuristic) on save so that when a 99-character name is loaded, it gets saved with 80 characters; alternatively you might have a property indicating that it's been grandfathered and some action should be taken.

If event-sourcing, you have some more options: the events with the old name are forever, but they can be reinterpreted in light of the new rule, or you can do tricks with snapshots and/or corrective events.