Tei*_*raz 5 domain-driven-design functional-programming scala aggregateroot
我已经阅读了几篇文章(也是这本书的书Functional domain modeling),他们提议将域对象的状态与行为分离,但是我无法理解这种方法在到达域模型上的优势。
这是一个到达域模型的示例:
case class Account(id: AccountId, balance: Money) {
def activate: Account = {
// check if it is already active, eg, enforce invariant
...
}
def freeze: Account = ???
}
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方式对此帐户进行连锁操作:
account.activate.freeze
Run Code Online (Sandbox Code Playgroud)
这是他们建议的“贫血”方法的示例:
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) => {
...
}
}
Run Code Online (Sandbox Code Playgroud)
在这里我可以像这样链接操作
activate andThen freeze apply account
Run Code Online (Sandbox Code Playgroud)
除了“优雅”的语法,第二种方法的优点是什么?
另外,在到达域模型的情况下,我将在单个类中强制执行不变式,但在“贫血”模型的情况下,逻辑/不变式可以跨服务分布
一个优点可能是能够向链添加另一个链接,而无需修改和重新编译域模型。例如,假设我们想添加另一个验证步骤来检查欺诈行为
object AccountService {
def fraud = (account: Account) => ...
}
Run Code Online (Sandbox Code Playgroud)
那么我们可以像这样组成这一步
(fraud andThen activate andThen freeze)(account)
Run Code Online (Sandbox Code Playgroud)
从概念上讲,添加fraud验证步骤并没有改变域模型的结构case class Account,那么为什么还要重新编译它呢?这是一种关注点分离的形式,我们希望将代码库的更改范围缩小到最小的相关部分。