【发布时间】:2015-11-22 18:46:37
【问题描述】:
我以 StackOverflow 为例,因为显然你知道那个网站,而且我的真实用例非常接近。
让我们想象一个简化的 SO 域描述:
- 有用户
- 用户可以创建新问题
- 用户可以为这些问题创建答案
- 用户可以编辑自己的问题和答案
- 如果用户的声望超过 1000 个,则用户可以编辑其他用户的问题(随机采用该阈值)
最后一条粗体规则对我来说很重要。
我对 AggregateRoot 的理解是,它应该包含用于决定接受或拒绝命令的状态,并且它不应该查询数据库来这样做。它保证了应用程序的一致性。它应该只监听它发出的事件来更新它的状态。
现在我认为 SO 域有一个名为 Question 的聚合根。 然后该问题将处理以下命令:
- 创建答案
- 编辑问题
问题是,当 EditQuestion 被触发时,Question AggregateRoot 将如何决定是接受还是拒绝该命令?因为如果你记得的话,如果你有
问题 AR 维护所有用户声誉的列表,以便能够知道如何执行该命令,这对我来说似乎没有意义。
问题在于,在尝试对我的域进行建模时,我一遍又一遍地遇到这个建模问题,而且我总是以一个大的 AggregateRoot 结束
有人可以告诉我我缺少什么并帮助我解决这个问题吗?谢谢
这个question 好像在说我们不应该把授权系统放在域模型里面。我同意这对于基于角色的身份验证之类的事情可能是实用的。但是,对我来说,“除非有足够的声誉,否则用户不能编辑”确实是一个 SO 业务规则,那么它怎么可能在域之外呢?
重要提示:在回答时,请考虑您是业务专家。您作为用户了解 StackOverflow,并且可以自己猜测 SO 约束是什么。即使您对它们有误,也没什么大不了的:只需针对您错误的业务限制提出建议即可!!!
这不是我第一次问这种问题,而且总是以没有答案而结束,只是无休止的讨论。我想知道的是,如果您必须构建此站点,您将如何为 StackOverflow 建模,重点是关于要编辑的最低声誉的业务规则。
【问题讨论】:
-
你不能总是依赖强一致性。如果用户是 1000,但在他编辑问题的同一秒内失去 50 声望,这真的很重要吗?它真正产生了什么样的业务影响?
-
它归结为 AR 大小,但聚合越大,您的争用就越多。正如 plalx 正确地说的那样,如果代表减少真的很重要吗?因此,请检查问题编辑方法中的 user.Reputation 属性(传入完整的用户对象)。如果您对此非常担心,那么可以使用 saga 将编辑提交实现为外部事务,该事务将完成或回滚并进入某个已知状态并通知相关方
-
@g18c 甚至不确定这将如何使用最终一致性进行建模?您是否会处理
UserReputationChanged事件,然后检查用户是否在其声誉降至某个阈值以下后修改了问题。如果确实如此,那么您将对问题执行补偿操作,例如撤消编辑并通知用户?我想您还必须处理QuestionEdited事件,以防事件出现故障? -
确实如此。我同意这种思路。但是,如果企业可以接受用户点在编辑开始和结束之间下降的可能性,那么它会变得更简单
-
@SebastienLorber 对您的设计而言,一个决定性的问题是,对于拥有 >1000 rep 的用户对 Q 的并发更改,您的政策是什么?最后一个赢了?合并?乐观锁定 ?等等
标签: domain-driven-design cqrs event-sourcing