Valid vs NOT valid objects?

passengers.

size < max_passengers endendWe allow adding any number of passengers in the reservation without raising an exception.

Both approaches are correct but what is the difference between them?When we chose the first approach (the entity is always valid), we do not have to worry about the inconsistent or invalid state of an object.

When we chose the second approach (The entity is NOT always valid) it allows us to gather all the validations of the entity in one place which simplifies the validation logic.

But which approach to choose?Although the not always valid approach provides better benefits I tend to like the is always a valid approach.

When releasing new features, I tend to think and consider different use cases that may something go wrong so I always raise an exception trying to keep the entity in a valid state.

That exception may not be raised at all but it’s hard to remember one time that I haven’t seen an exception being raised.

It’s always one use case that is missing.

Moreover, you keep protecting your entity based on business rules.

This is because of the requirements not being communicated correctly (or not completely understandable/predictable) or because you don’t have control on external dependencies and you cannot guarantee the input that will be given in your domain services.

Other than that, there may be use cases where you or the business owner have not anticipated.

Unhappy paths or weird use cases that it's hard to predict.

I like to think every business process like parsing an input request from a user.

You don’t trust it.

You can never know it’s validity or what the input will be.

So you have validation logic and authorization logic.

The same happens with business processes as well.

Why should you process an invalid request?.No need to do so.

So I prefer having entities in my domain that will be always valid.

No matter what, the invariants should be fulfilled and maintained during its lifecycle.

Except the above consider also the following:Introducing an is_valid?.method would force the client to always call it in order to check what to do next.

Checking that the invariants are maintained with the is always a valid approach promotes DRY principle and eliminates duplication.

Imagine during a business process checking if an entity is valid all the time?It’s better to follow business rules telling that an entity cannot be in state A rather than having it in a state B and search around why, how and when it went there.

A violation of the invariants should signalize a bug and lead to a failure in order to protect the business rules.

Last but not least it follows DDD principles.

Promotes fail fast principle.

The last question would be where to check for business validations since all our domain objects have a valid state.

For example when or where whould we check if we can add a passenger to the reservation?.That is an easy question to answer.

This kind of validation logic should be added to the application services.

That would be our boundaries on top of our domain layer in clean architecture or onion architecture.

An example is shown below:# .

some application serviceresult = flight_reservation.

check_validityresult.

then { |data| flight_reservation.

book }.

or_else { |err| handle_error(err)}SummarizeDomain entities should always respect their constraints and invariants.

They should always be in a valid state during their lifetime.

If we need to check for their state we should do so in the application services layer before performing an action.

That way we ensure that our domain entities will be in a valid state before executing an action.

References[1] https://www.

pluralsight.

com/courses/domain-driven-design-in-practice?gclid=Cj0KCQjwt_nmBRD0ARIsAJYs6o0eubu0-DAky3nxtM6ZLaaXd9zzjyObWMVMMLvqsKE0lsEdydbUimcaArxiEALw_wcB&ef_id=Cj0KCQjwt_nmBRD0ARIsAJYs6o0eubu0-DAky3nxtM6ZLaaXd9zzjyObWMVMMLvqsKE0lsEdydbUimcaArxiEALw_wcB:G:s&s_kwcid=AL!5668!3!339565055182!b!!g!!&aid=7010c000002SNseAAG&promo=&oid=&utm_source=non_branded&utm_medium=digital_paid_search_google&utm_campaign=EMEA_DE_Dynamic&utm_content=[2] https://en.

wikipedia.

org/wiki/Domain-driven_design[3] https://www.

infoq.

com/articles/ddd-in-practice.

. More details

Leave a Reply