I've read several articles (also the book Functional domain modeling
) where they propose to decouple state of the domain object from the behavior, but I cannot understand advantage of such approach over reach domain model.
Here is an example of reach domain model:
case class Account(id: AccountId, balance: Money) {
def activate: Account = {
// check if it is already active, eg, enforce invariant
...
}
def freeze: Account = ???
}
I can chain operations with this account in following way:
account.activate.freeze
Here is example of "anemic" approach which they suggest:
case class Account(id: AccountId, balance: Money)
object AccountService {
def activate = (account: Account) => {
// check if it is already active, eg, enforce invariant
...
}
def freeze = (account: Account) => {
...
}
}
And here I can chain operations like this
activate andThen freeze apply account
What is the advantage of the second approach except of "elegant" syntax?
Also, in case of reach domain model, I will enforce invariants in single class, but in case of "anemic" model, logic/invariants can spread across services
fraud
to the service layer method seems like just moving logic in to another place, same can be achieved just adding new method to Account, plus everything will be in the one, central place, within Account which all this logic belongs to, enforcing invariants and logic will not spread across several places so seems like reach model is more intuitive and "clear" approach. – Mahau