1

在领域驱动设计中,强调将行为放在正确的位置。不过,我并不总是确定究竟什么是“正确的”。

考虑这种情况:“客户从银行账户中提取了一笔钱。”

从语法上讲,我们有:

  • “客户”是一个主题

  • “撤回”是动词

  • “金额”是直接对象

  • 'account' 是一个受影响的介词宾语

传统上,客户端会执行这个:account.withdraw(amount)

这可以理解为:“客户命令银行账户提取一笔钱。” 然而,这在语法上并不对应于原始场景,因为“银行账户”现在是直接宾语,并且不定式从主子句中删除了“提款”和“金额”,因此传达的主要思想是“客户命令账户” .

要遵守 DDD,我们应该将这段代码视为对原始场景的精确描述。这意味着 'withdraw' 方法不会模拟帐户执行的行为(帐户不是主题),而是模拟间接影响它的行为(帐户是介词宾语)并且很可能被重命名'wasWithdrawnFrom'。此外,方法参数表示受客户端而不是对象影响的事物(它是客户端主体的直接对象,而不是对象主体)。

如果我们从这个例子中推断,我们可以看到方法可能代表影响对象的行为(对象不是主体),方法参数可能代表客户主体的直接对象

然而,方法是否应该代表对象执行的行为尚不清楚。

所以我的问题是:我们应该如何使用方法来建模对象行为?

1) 方法应该严格表示影响对象的行为。(宾语不能作为主语,只能作为语法直接/间接/介词宾语)

2) 方法既可以表示影响对象的行为,也可以表示对象执行的行为。(宾语可以作为主语或语法直接/间接宾语)

4

3 回答 3

0

我发现这种场景太简单而无法实现,因此也太简单而无法建模。我会重新制定

“客户从银行账户中提取了一笔钱。”

类似于

“客户从他的账户提交价值 xxx 美元的取款请求”(当我去我的银行时,我必须填写一张表格才能取款,其中注明金额、帐号、日期和我的签名)

可以从他的帐户(由 ID 标识的帐户)和货币价值(作为价值对象的货币)中发现对客户(由 ID 标识的客户)的服务(提款服务)的请求(命令)。

于 2013-10-07T22:03:17.627 回答
0

我不太关心语法,因为英语是我的第二语言,所以在尝试理解领域时,我尝试了解业务如何看待概念(帐户)和工作流程(提取金额)而不是进行语法分析.

DDD 的重点是对业务中的事物进行建模,因此行为会根据领域理解出现。

在这种情况下,对我来说,很明显我们在 Account Operations Bounded Context 中工作,并且至少涉及 Account 聚合根。当然,在银行方面,可能(我在这里猜)不会有提款,而是增加账户借方/贷方部分的操作,因此该账户很可能会注册借方/贷方操作已经发生. 一个领域事件诞生并发布。然后让领域专家告诉你接下来会发生什么。

"客户删除订单" => order.delete

订单可能永远不会被删除,但其状态将更改为“已取消”或类似。但是,对于确实应该删除订单的情况,订单不会自行删除,订单存储库会删除该订单。

于 2013-10-08T07:32:23.913 回答
0

您似乎陷入了理论论文中。我不确定您是否可以应用适用于每个场景/项目的理论。当您开始用用例轰炸您的模型时,通常会出现行为。我试图让案例决定行为。按照你的例子:

演员客户想从账户中取款。这样做的方法就像你做 Account.Withdraw(Money amount)

但是您的问题“我们应该如何使用方法来建模对象行为?” 是一个常见的 DDD 问题。如何用行为丰富你的模型?我最好的提示是找到你的值对象。值对象通常带有行为。

在示例中,帐户是和实体(可能是聚合根)。货币(具有货币和金额的价值对象)应从账户中提取。那应该是账户单一责任人(原则)来控制账户余额和对其的所有访问。最后关于你的(2)问题。方法绝对用于更改对象的内部状态。但是当涉及到像 Customer.Order(newOrder) 或 advert.Apply(candidateCV) 这样的实体/值对象执行的行为时,我们可以让实体相互通信。我们还可以通过域事件创建链式行为,这可以帮助我们不向应用程序服务泄漏太多业务逻辑。请参阅 Udi Dahan 的博客或我关于贫血域模型的博客文章http://magnusbackeus.wordpress.com/2011/05/31/preventing-anemic-domain-model-where-is-my-model-behaviour/

我希望你有一些想法。当我们在这里如此抽象时,很难给出具体的提示。/最好的问候马格努斯

于 2013-10-07T20:55:31.037 回答