背景
我正在尝试将ddd和事件源应用于我的项目的一部分。
这是一个拍卖应用程序。
Customer
注册Item
,当管理员Auction
STARTED
时approves
是Item
。Auction
具有duration
,它允许Bidder
中的Bid
到duration
。Auction
被认为是ENDED
,因为duration
和Bidder
无法出价。Auction
,即使遇到ENDED
,maximum bids limit
还是duration
。Customer
可以在select
和Bid
中duration
一个5 days after the duration ends
。 Auction
EXPIRED
和Customer
不能select
到Bid
。申请要求:
Bidder
应该能够查询可竞价的拍卖。ended
和expired
拍卖的通知。总而言之,我定义了我的经典DDD域模型:
实体:Auction
,Bid
,Customer
,Administrator
,Bidder
值对象:AuctionStatus
(STARTED
,ENDED
,EXPIRED
,SELECTED
)
总根:Auction
,Customer
,Bidder
,Administrator
问题
问题是我不确定是否应该
A)定义一个类似AuctionEndedSpecification
的规范,并使用它来查询和判断状态和约束操作。
或
B)将EndAuction
视为命令,并将简单属性status
放入Auction
A的难解部分:要判断拍卖是过期还是结束,我需要当前时间,这会使代码更难以实现。而且我认为实现查询方面可能会更困难。
B的棘手部分:拍卖由于多种原因而结束(持续时间已过,遇到最高出价限制)。我了解到让一个事件触发另一个事件不是一个好习惯。但是在这种情况下,BidAdded
事件可能会触发AuctionEnded
事件。另外,如果我通过计划的任务来管理到期时间,那感觉就像我的域模型假设读取侧的简单性与应用程序需求高度相关。
如果您遇到了类似的问题,请帮助我解决您的问题。
答案 0 :(得分:0)
显然,可以从事件中计算出拍卖汇总状态,而无需任何其他事件。在写端和读端都可以。
为什么仍要添加AuctionEnded事件的原因是:
拍卖endind的规则将来可能会改变,这样您的计算逻辑就会变得很复杂。
您有一个外部服务,它不想自己计算拍卖结束状态。
有一个一般性建议,即域专家应读取您的聚合事件流。我想我想在这样的流中看到“ AuctionEnded”标记。
如果您决定制作AuctionEnded事件,则需要Saga / ProcessManager在适当的时候发出“ EndAuction”命令。
答案 1 :(得分:0)
要判断拍卖是过期还是结束,我需要当前时间,这使得代码难以实施。
我请您注意John Carmack
的写作如果您不考虑时间是输入值,请仔细考虑直到它成为输入值-这是一个重要的概念
为了澄清起见,我添加了域模型;通常不需要将时钟推到应用程序边界之外。
选择采用哪种方法的一个关键想法-领域模型是决定拍卖何时结束的权威,还是只是跟踪其他地方的决策?
您的第一种方法与模型是权威的想法保持一致;应用程序会告诉模型现在几点,模型决定是否结束拍卖。
您的第二种方法与该模型仅仅是簿记的想法一致-来自“ 此”模型外部的“最终拍卖”。
这两种方法都是正确的,具体取决于您要构建的内容。
鉴于您的其余描述,我认为您正在尝试建立第一种类型的解决方案,因此您应该考虑告诉领域模型什么时候是什么,然后让模型决定是否表示拍卖结束了。
警告:正确设置管道可能会很痛苦:应用程序如何知道哪些拍卖需要时间?重新启动应用程序后,时间表是否会保留?等等。